USB_Reset_Suspend_Resume

Reset 整个reset过程,host需要拉低D+的时间\(T_{DRST}\) 至少 > 10ms。 High-speed capable hubs and devices在reset过程中还会执行一套reset protocol: Hub确认接的设备不是Low-speed, 如果是low-speed,不会有下面的reset握手协议。 Hub把D+拉低,进入SE0状态。 Device检测到SE0: 如果device是从suspend状态进入reset,那么device在不少于2.5us后进行high-speed detection handshake。 如果device是从non-suspend full-speed状态进入reset,那么device需要在2.5us~3ms之间进入handshake。 如果device是从non-suspend high-speed状态进入reset,那么device必须在3ms~3.125ms之间恢复full-spped,通过断开高速终端电阻以及重新接上D+的上拉电阻。接着在100us-875us内开始检测SE0状态,进入handshake。 Device往D-灌电流,形成一个800mv左右的ChripK信号, 该信号保持1~7ms。 Hub检测到ChripK信号后,100us内需要发送三对KJ(k-J-K-J-K-J)。每个单独的J或K都要保持40~60us。KJ对打完之后,在500us内断开D+上拉电阻,使能高速终端电阻,进入高速状态。 Suspend Device有两种进入suspend的方式: 如果连续3帧没有收到SOF包(1ms一帧),device会进入suspend状态。 host driver发送SET_PORT_FEATURE(PORT_SUSPEND)给hub,hub再发送给指定的device。 Resume 从suspend状态resume起来需要保持ChripK状态20ms以上,也有两种方式: Device remote wakeup,device drive K-state 1~15ms。Hub会在1ms内,接管D+, D-,继续产生resume信号直到20ms。 host发送CLEAR_PORT_FEATURE( PORT_SUSPSEND)给hub,hub drive K-state 20ms。 Reference Reset, Suspend, and Resume Commands USB全速设备的挂起、唤醒Resume USB2.0设备从全速模式到高速模式的识别过程及速率协商 USB spec 7.1.7.5~7.1.7.7, 11.9

2024-03-29 · 1 min

Operating Systems Three Easy Pieces(OSTEP) - Memory Virtualization

Chapter14 Memory API 14.2 The malloc() call 分配字符串长度的时候要注意:malloc(strlen(s) + 1),多分配一个byte给\0。strlen函数计算长度不会统计\0。 14.4 Common Errors Not Allocating Enough Memory char *src = "hello"; char *dst = (char *) malloc(strlen(src)); // wrong!!! char *dst = (char *) malloc(strlen(src) + 1); strcpy(dst, src); // work properly strcpy拷贝的时候会把\0也拷贝过去,所以分配长度的时候要strlen()+1。 否则多拷贝的一个byte,会写到heap的其他变量所属的地址,可能会导致fault。 Forgetting to Initialize Allocated Memory malloc分配出来的内存,需要初始化,否则可能是随机内存值。 Forgetting To Free Memory malloc分配出来的内存需要free掉。不然长时间运行的进程会导致内存泄漏。 短时间运行就结束的进程可能不会有这个问题,在进程结束后系统会自动回收内存,但free掉不使用的内存仍然是一个好习惯。 Freeing Memory Before You Are Done With It Freeing Memory Repeatedly Chapter15 Address Translation 地址转换 Chapter16 Segmentation 分段 16....

2024-03-27 · 1 min

Operating Systems Three Easy Pieces(OSTEP) - CPU Virtualization

这篇文章是阅读 OSTEP 3~11 的笔记,主要讲的是 Virtualization 中 Virtualize CPU 的部分。 Chapter4 Process 4.2 Process API 一般 OS 会提供以下的进程 API 来操作进程: Create: 创建进程。 Destory: 结束进程。 Wait: Wait a process to stop running. 等待进程结束。 Miscellaneous Control: Suspend/Resume… 休眠,唤醒等等。 Status: 查看进程状态。 4.3 Process Creation 首先 OS 将存储在 disk or SSD 的 program 程序加载进 memory 内存。 这边有两种方式,一种是在运行前把 code 和 static data 全部加载进内存。现代操作系统一般会使用第二种方式,懒加载,只加载即将使用的 code 和 data。 分配栈。 分配堆。 分配三个文件描述符,标准输入 0,标准输出 1,错误 2。 4.4 Process Status 进程的状态有:...

2024-03-21 · 5 min

xv6_chapter4 Traps

Lecture gdb调试shell write函数的syscall过程: (gdb) b *0xdec # 在0xde8地址设置断点 (gdb) c (gdb) delete 1 # 删除断点 (gdb) print $pc $1 = (void (*)()) 0xdec (gdb) info r (gdb) x/3i 0xde8 # 打印0xdfe开始的三条指令 0xdfe: li a7,16 0xe00: ecall 0xe04: ret (gdb) p/x $stvec $2 = 0x3ffffff000 # user space virtual address顶部一个page,trampoline page对应kernel trap handler. (gdb) stepi warning Book Traps: system call. 通过ecall进入kernel exception. 除0,invalid virtual address. interrupt. 进入kernel device driver. 根据处理代码不同,可分为三种traps: traps from user space traps from kernel space timer interrupts 4....

2024-02-26 · 1 min

xv6 calling conventions and stack frames RISC-V

caller: not preserved across fn call. 需要调用函数来保存寄存器。参考下面例子中的ra寄存器值。 callee: preserved across fn call. 被调用函数来保存寄存器。 根据CSAPP 3.7.1栈结构看,return address属于前一栈帧保存的,所以fp register应该指向return address的地址,即当前栈帧的顶部。一个栈帧中保存在最高位地址的是previous fp。所以这里最上面一个stack frame也应该把return address去掉。 sum_to: mv t0, a0 li a0, 0 loop: add a0, a0, t0 addi t0, t0, -1 bnez t0, loop ret // 返回到li t0, 2 sum_then_double: addi sp, sp, -16; // 分配栈空间 sd ra, 0(sp) // ra的值存入sp+0地址。caller保存sum_the_double执行完的返回地址 call sum_to // 这里调用call,ra的值被设置为下一条指令地址,即li t0, 2 li t0, 2 mul a0, a0, t0 ld ra, 0(sp) // 恢复sum_them_double的返回地址 addi sp, sp, 16 ret

2024-02-25 · 1 min

Zephyr -- Board Porting Guide

Board/ 添加自定义的board:boards/<arch>/<board>/ boards/<ARCH>/plank ├── board.cmake ├── CMakeLists.txt ├── doc │ ├── plank.png │ └── index.rst ├── Kconfig.board ├── Kconfig.defconfig ├── plank_defconfig ├── plank.dts └── plank.yaml 必须要有的文件: plank.dts:设备树。 Kconfig.board, Kconfig.defconfig, plank_defconfig: Kconfig文件。 可选文件: board.cmake: 用于west flash和west debug。 CMakeLists.txt: 如果在board/下加其他*.c的话需要。 doc/: 文档。 plank.yaml: Test Runner(Twister)需要使用。 Kconfig.board: 至少需要config BOARD_PLANK选项。 config BOARD_PLANK bool "Plank board" depends on SOC_SERIES_YOUR_SOC_SERIES_HERE select SOC_PART_NUMBER_ABCDEFGH Kconfig.defconfig: 板子的一些固定Kconfig选项,需要包括在 if BOARD_PLANK/endif中间。通常是invisible Kconfig Symbol,没有prompt。需要依赖default值或者其他Kconfig依赖,无法在配置菜单中选择。 if BOARD_PLANK # Always set CONFIG_BOARD here. This isn't meant to be customized, # but is set as a "default" due to Kconfig language restrictions....

2024-02-01 · 1 min

xv6 Misc

xv6运行 make qemu make clean Ctrl-p 打印进程。 Ctrl-a x 退出qemu。 make grade 检查所有lab得分。 ./grade-lab-util sleep or make GRADEFLAGS=sleep grade 检查某一项作业得分。 GDB 调试 sudo aptitude install gdb-multiarch: 解决ubuntu22.04 gdb版本不匹配的问题。 一个shell运行make qemu-gdb, 另一个shell运行gdb-multiarch,会自动加载.gdbinit。如果出现如下错误: warning: File "/home/xyc/MIT-6.S081-Operation-System/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load". To enable execution of this file add add-auto-load-safe-path /home/xyc/MIT-6.S081-Operation-System/.gdbinit line to your configuration file "/home/xyc/.config/gdb/gdbinit". 按照提示操作,将add-auto-load-safe-path /home/xyc/MIT-6.S081-Operation-System/.gdbinit加到/home/xyc/.config/gdb/gdbinit即可。

2024-02-01 · 1 min

xv6_lab3 pgtbl

Q1 Speed up system call 这个实验的目的是将用户程序的虚拟地址USYSCALL映射到保存有进程pid的物理地址。 这样不用通过系统调用getpid()的方式,直接通过ugetpid()访问虚拟地址就可以直接得到映射的进程pid。 #define USYSCALL (TRAPFRAME - PGSIZE) // USYSCALL位于虚拟地址顶部Trapframe下面一个page int ugetpid(void) { struct usyscall *u = (struct usyscall *)USYSCALL; // 直接访问虚拟地址 return u->pid; } 在struct proc进程结构体中增加struct usyscall *usyscall, 在分配进程函数allocproc中初始化, 分配p->pid给p->usyscall->pid: if ((p->usyscall = (struct usyscall *)kalloc()) == 0) { freeproc(p); release(&p->lock); return 0; } p->usyscall->pid = p->pid; 在给进程分配页表的函数proc_pagetable()中映射指定的虚拟地址。 注意要加上PTE_U p->pagetable = proc_pagetable(p); pagetable_t proc_pagetable(struct proc *p) { // ... // map the USYSCALL just below trapframe....

2024-02-01 · 2 min

Zephyr -- Misc

生成compile_commands.json 执行如下命令, 再编译后, build目录下生成 compile_commands.json, 可以帮忙IDE进行代码的诊断, 补全和跳转: west config build.cmake-args -- -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 编译过程保留.i文件 west build -- -DCMAKE_C_FLAGS="-save-temps=obj" 会保存到build/目录下各层级的CMakeFiles中。 全局变量分析 利用puncover工具,build完之后运行: west build -t puncover Test命令 编译检查: west twister -p rts5816 -T fingerprint/apps/usbfp 在板子上运行测试(需要host和板子连接): west twister -p rts5816 -T fingerprint/tests --device-testing --device-serial /dev/ttyUSB0 --device-serial-baud 57600 单元测试: west twister -p unit_testing -T fingerprint/tests

2024-01-31 · 1 min

Zephyr -- Kconfig

Setting Kconfig configuration values 生成的配置文件: zephyr/build/.config: for CMake use. zephyr/build/zephyr/include/generated/autoconf.h: for c file use. 所有的Kconfig配置会merge如下路径的Kconfig files: board/<arch>/<BOARD>/<BOARD>_defconfig CMake中定义的CONFIG_XXX Application configuration(APP 目录下的Kconfig相关文件) 第三点Application configuration又会从如下路径获取Kconfig,默认使用prj.conf: 如果定义了CONF_FILE, 会把该文件的Kconfig merge进来。CONF_FILE可以在如下定义 App的CMakeLists.txt, 在find_package(zephyr)前定义。 west直接传入-DCONF_FILE=<conf file(s)> From the CMake variable cache 如果未定义CONF_FILE, 如果存在prj_<BOARD>.conf,merge进prj.conf。 如果存在board/<BOARD>.conf,merge进prj.conf。 如果存在board/<BOARD>_<revision>.conf,merge进prj.conf。 merge必须有的prj.conf。 如果board/下的<BOARD>_defconfig和APP/下的Kconfig冲突了,以APP的为准。

2024-01-31 · 1 min