嵌入式基础常识

2023-11-19

一、

基本概念

linux       @           ubuntu     :~$ 
用户名 类型:普通用户   系统名称   家目录

root
管理员用户

pwd  显示当前工作路径(绝对路径)

/home/linux  家目录    /$根目录下  /代表根目录

ls 列出文件状态   + 选项 (-l  -i   -h  -1)

rwx                             r-x                                 r--
文件所属用户对该文件执行权限    同组其他用户对该文件的执行权限      非同组其他用户对文件的执行权限
读 写  执行均可                 可读  不可写   可执行               只可读  不可写 不可执行

文件类型 七种:
b    block     块设备文件       例如:U盘  硬盘  按内存块读取
c    char      字符设备文件     例如: 键盘  鼠标    按字符读写   先进先出原则
d              目录
-              普通文件
l              链接文件
s    socket    套接字文件
p    pipe      管道文件

cat +文件名  显示文件信息    rm +文件名   删除文件   cp +被复制的文件名+新文件名  复制文件
mv  +被剪切的文件+新文件名   剪切文件     mkdir  创建文件夹 /目录    rmdir  删除空目录     touch  创建一个新文件   
clear 或者  CTRL+l   可以清屏
rmdir 不能删除非空目录     rm  +  文件名  +  -rf    可以删除所有目录

cd    切换目录     cd  +  -   切换到上一次切换的目录

grep 查询关键字   +    关键字名称   +   路径名   +    -rn  逐个目录查找/递归搜索

二、

vim编辑器

模式:1.底行模式  :wq  保存并退出   :q!  强制退出不保存     shift+zz  保存并退出     
                    esc后 + yy 复制光标所在行 + p  复制    dd  剪切一行    按d剪切所有  按y复制所有     u 回复上一次状态
     
      2.命令行模式/输入模式
                  vsp  +  文件名  分屏        :wqa退出所有分屏       
                   vi + -O + 文件名+ 文件名  直接打开分屏  大写O左右分屏 小写  上下分屏


CTRL+alt+T  重新打开一个家目录下的编辑界面

sudo su   进入root用户

sudo shutdown -h now 关机    -r  now  重启  ==   sudo reboot  now


三、

shell命令

head  +  行数 +    显示文件开头
tail  +  行数 +    显示文件结尾
diff     比较两个文件
file     查看文件类型 
echo     显示文本信息   》代表输出    》》代表继续输出   在终端输入文件到设备中
         + 字符串  +  》(重定向) +  文件名   清空方式
         + 字符串 +   》》(重定向)+ +文件名  追加的方式  
df       + -TH    检查文件系统空间占用情况
du       + -mh   查看文件大小
chmod    改变文件或目录的访问权限
         sudo chmod   755  +  文件名

man      linux官方文档

passwd  用户密码   sudo  passwd  +用户名(linux)

四、文件压缩以及解压

gzip  +  - 级别(1-9)+  文件名   1-9为压缩级别  越大压缩越小
gunzip  + -f    +  压缩文件名         解压
gzip    + -l    +  压缩文件名         查看压缩比


tar 归档 压缩 解压
tar -c  创建一个归档文件
    -f  指定归档文件名称
    -x  释放归档文件
    -v  显示归档以及释放过程

    -j  由tar生成归档 由bzip2压缩
    -z  由tar生成归档 由gzip压缩

归档并压缩
    -cjf  +  压缩文件名 + 需要压缩的文件夹
    -czf  +  压缩文件名 + 需要压缩的文件夹
 
解压 

tar -xvf + 压缩文件名    便可直接解压
 
gcc 编译器
 
gcc + 文件名  编译文件
gcc + 文件名  +  -o  + 生成可执行程序名
 
执行: ./执行程序

五、编译器编译源码:

预处理(pre-processing)  xxx.c--->  (预处理文件)
编译(compiling)         xxx.i--->  (汇编文件)
汇编(assembling)        xxx.s--->  (可重定向文件)
链接(linking)           xxx.o--->   (可执行文件)

预处理:gcc -E test.c -o test.i
编译:  gcc -s test.i -o test.s
汇编:  gcc -c test.c -o test.o
链接:  gcc test.o -o test
 
makefile 
makefile格式

变量名称($)
$<  第一个依赖文件的名称
$^  所有不重复的依赖文件 以空格分开
$@  目标文件的完整名称

  
六、静态库、动态库
静态库:
1.将功能函数所在文件编译成可重定向文件
   gcc -c func.c -o func.o
2.将可重定向文件制作成静态库
   ar crs libfunc.a func.o
3.编译时,指定库的路径及库的名字
  gcc main.c -o main -L. -lfunc

动态库:
1.将功能函数所在的文件编译成可重定向文件
   gcc -fPIC -c func.c -o func.o
2.将可重定向文件制作成动态库
   gcc -shared func.o -o libfunc.so
3.生效,将库文件存放到/lib
  gcc main.c -o main -L. -lfunc  不可执行
  sudo cp libfunc.so  /lib/      转移路径后
  ./main                         便可执行
  


七、存储结构:
数组:
     一维数组:数组名   《==》数组的首地址,数组的起始地址, 首元素地址
     一维数组数组名:列性质地址  
     *(array+i)每次移动到下一位地址(列发生偏移)
     *  代表解引用 ,根据数据所在地址,获取该地址上的内容
 
     二维数组:数组名 《==》数组的起始地址 ,
     二维数组数组名   :行性质地址
     a[]:               列性质地址
     &a[0][0]:          列性质地址
 
    *(*(a+i)+j)  括号中*,表示降级处理,将a+i由行性质地址转换为列性质
    结论:
    a【i】  《=====》  *(a+i)
    一维数组中* 代表解引用
    二维数组中* 代表降级处理

指针:
    指针变量在内存上占有四个字节,与其指向无关
    普通指针是列指针, 保存的是指向的数据所在的内存的地址

数组指针:
    指向数组的指针,不同于普通指针,数组指针是行指针
    例如:int(*p)[4];

指针数组:
    数组,  数组中的元素是指针(普通指针或函数指针),保存的是地址

结构体:
       struct 结构体名
           {
              成员名:
              成员名:
              。。。。
           };
      结构体(初始化  赋值 获取结构体成员的值)
          1.变量名:
            变量名.成员名==值;
          2.指针:
            指针变量名指向成员名
            p=&test;先指向结构体名


八、IO:

input    output    输入 输出  

文件IO: 采用系统调用的方式对文件进行读写
         对文件进行读写的功能由内核完成--系统调用
         
 操作方式:先打开(open),后读(read)写(write)
 
 函数原型:int open(const char *pathname, int flags);
           int open(const char *pathname, int flags, mode_t mode);
 功能:打开一个文件或设备
 参数:pathname 路径名(文件名)
       flags    当前进程对该文件的操作权限
                O_RDONLY     以只读的方式打开文件
                O_WRONLY     以只写的方式打开文件
                O_RDWR       以读写的方式打开文件
                
                O_APPEND     以追加的方式打开文件
                O_CREAT      如果文件不存在,自动创建
                O_TRUNC      如果文件中有数据,清空数据
                
        O_RDONLY   以只读的方式打开文件,文件必须存在,不存在,出错
    O_RDWR     以读写的方式打开文件,文件必须存在,不存在,出错
    O_WRONLY|O_CREAT|O_TRUNC    以只写的方式打开文件,如果文件不存在,自动创建,
                                如果文件已存在,清空文件原有的数据
    O_RDWR|O_CREAT|O_TRUNC    以读写的方式打开文件,如果文件不存在,自动创建,
                                如果文件已存在,清空文件原有的数据
    O_WRONLY|O_CREAT|O_APPEND   以只写的方式打开文件,如果文件不存在,自动创建,
                                如果文件已存在,已追加方式进行访问                                 
    O_RDWR|O_CREAT|O_APPEND   以读写的方式打开文件,如果文件不存在,自动创建,
                                如果文件已存在,已追加方式进行访问                            
       mode   当flags指定O_CREAT,必须有第三个参数  
              mode:该文件所属用户对该文件的执行权限  
              例:0664    
              mode & ~umask(文件权限掩码)              
                                
返回值: 成功  文件描述符(非负数)
           失败  -1  
                                
当程序打开文件,文件描述符的值从3开始,0,1,2系统默认自动打开                                                                
  0:标准输入
  1:标准输出
  2:标准出错输出 

#include <unistd.h>头文件
函数原型:ssize_t write(int fd, const void *buf, size_t count);
          功能:向文件中写入count个字节的数据
          参数:fd  文件描述符
                buf 写入到文件的数据
                count 需要写入到文件的字节数

         返回值:  成功   实际写入的字节数
                   失败   -1
函数原型:ssize_t read(int fd, void *buf, size_t count);
          功能: 期望读取count个字节的数据
          参数:fd  文件描述符
                buf 保存读取的数据 
                count 期望读取count个字节的数据
 
          返回值: 成功 实际读取的字节数
                   失败  -1

九、进程

进程是一个程序的一次执行的过程

进程和程序的区别:
程序是静态的,它是一些保存在磁盘上的指令的有序的集合,没有任何执行的概念
进程是一个动态的概念,他是程序执行的过程,包括创建,调度,消亡

进程的创建:当程序开始执行时,系统会为每一个进程分配4G的虚拟地址空间,保存进程的资源
            并且会为每一个进程创建task_struct,描述进程的状态信息,或者进程资源

调度: cpu的调度或者时间片轮转调度
       时间片:进程在某一时刻获取cpu控制的时间

消亡(退出):进程退出,将该进程获取的有限资源全部释放

静态查看进程信息:ps  +  axj/(aux)

PPID(parent procss ID)     PID (process ID)      PGID(process croup ID)   SID(session ID)      
父进程ID号                   进程ID号                进程组ID号 (组长ID号)     会话组ID(会话组组长ID号)
 
TTY    TPGID   STAT          UID                   TIME                        COMMAND
终端           进程的状态     当前进程所属用户ID     进程获取CPU的控制总时间      进程名

CTRL + c 将进程退出     CTRL + z 将进程停止   bg 将进程放到后台执行(脱离终端控制)  fg 将进程放到前台


十、系统

系统移植

Windows装机: BIOS界面----》引导界面----》烧写Windows镜像----》加载当前文件系统
     
bootloader(引导系统)----》linux镜像----》文件系统(运行应用程序)

    uboot:
           driver(驱动)


tftp服务器:(配置)
  
检测: sudo dpkg -s tftpd-hpa  

在线安装:sudo apt-get install tftp-hpa tftp-hpa
         失败的话更新数据源:sudo apt-get install update
                                                                     
配置服务器端: sudo vi /etc/default/tftpd-hpa   以管理员模式进入编辑

修改代码: TFTP_USERNAME="tftp"                                                        
          TFTP_DIRECTORY="/tftpboot"
          TFTP_ADDRESS="0.0.0.0:69"
           TFTP_OPTIONS="-c -s -l"

改权限: sudo chmod 777 tftpboot   将tftpboot改成777最高权限   sudo mkdir tftpboot  在根目录下创建

配置参数:-c   create   可上传新文件
         -s   server    uboot默认tftpboot目录为传输目录
         -l   listen    监听           

启动tftp服务器: sudo service tftpd-hpa restart

nfs服务器

配置nfs服务器端: sudo vi /etc/exports  
                  
                 在11行添加代码: /source/rootfs/ *(rw,sync,no_subtree_check,no_root_squash)
  
/source  共享目录  自行创建   sudo mkdir source--》创建目录   sudo chmod 777 source--》改权限

rw 读写   sync 文件系统中的文件可以同步到内存与硬盘

no_subtree_check  如果子目录可以被访问,就不检测父目录的权限了

no_root_squash    如果以root用户进入文件系统,将不会检测权限

启动nfs服务器: sudo /etc/init.d/nfs-kernel-server restart


联网:

重启网卡:sudo /etc/init.d/networking restart 


十一、uboot

bootloader  操作模式:1.自启动模式  2.交互模式

setenv 设置新的环境变量

bootcmd  自启动命令、自启动模式、自动执行bootcmd后的参数

printenv 显示配置的环境变量

tftp 远程传输  tftp + address + file(二进制)

bootargs  uboot设置好,给内核使用

bootm    解压并启动该地址上的内容     bootm + address


dmesg 查看内核打印缓冲区的内容   sudo insmod driver.ko  插入内核    
lsmod 查看   sudo rmmod driver 卸载   modinfo driver.ko 查看
sudo dmesg -c  先查看,后刷新缓冲区 
sudo dmesg -C  直接刷新缓冲区
sudo mknod /dev/led c 500 0    执行

十二、

字符设备驱动框架

 1)设备号,驱动通过不同设备号区分不同的设备
        申请注册设备号:1)用户自定义,向内核注册
                        2)系统分配,再注册
 2)驱动需要实现对设备的控制(实现应用层对设备操作的函数接口)
 3)设备节点(文件),给应用程序,应用程序视设备为文件
  
设备号

 设备号(32bit)= 主设备号(高12bit)  +  次设备号(低20bit)

 #define MINORBITS    20
 #define MINORMASK    ((1U << MINORBITS) - 1)

 #define MAJOR(dev设备号)    ((unsigned int) ((dev) >> MINORBITS))  根据设备号,得出主设备号
 #define MINOR(dev设备号)    ((unsigned int) ((dev) & MINORMASK))   根据设备号,得出次设备号
 #define MKDEV(ma主,mi次)    (((ma) << MINORBITS) | (mi))   根据主次设备号,生成设备号
  
 申请注册:
     1)静态注册(用户自定义设备号,向内核注册)
        #define major 500
        #define minor 0
        
        dev_t devno = MKDEV(major, minor);
     
        函数原型:int register_chrdev_region(dev_t from, unsigned count, const char *name)
        功能:注册设备号
        参数:from  设备号(用户自定义)
              count 表示的是注册设备号的数量
              name  名字 (描述设备号)
        返回值:成功   0
                失败   负数
              
     2)动态注册(系统自动分配,向内核注册)
                函数原型:int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,                                                      const char *name)
        功能:系统分配设备号,并且注册
        参数:dev  系统自动分配设备号
              baseminor  次设备号
              count  注册设备号的数量
              name   名字  描述设备号
        返回值:成功  0
                失败  负数        

     3)注销   void unregister_chrdev_region(dev_t from, unsigned count)
            功能:注销设备号
        参数:from 设备号
              count  设备号的数量


如何实现对设备的控制
 
对于字符设备来讲,内核中提供结构体来描述一个设备strcut cdev

如何实现设备控制

 对于字符设备,内核提供结构体来描述一个设备struct cdev
 struct cdev {
    struct module *owner;    THIS_MODULE;
    const struct file_operations *ops;   对设备进行操作的集合
    dev_t dev;             设备号
    unsigned int count;
};

 1)初始化结构体
 
 函数原型:void cdev_init(struct cdev *cdev, const struct file_operations *fops)
 功能:初始化cdev结构体
 参数:cdev  cdev结构体
       fops  对设备操作集合
 
 2)将cdev结构体添加到内核链表
 
 函数原型:int cdev_add(struct cdev *p, dev_t dev, unsigned count) 
 功能:将cdev结构体添加到内核链表
 参数:p   cdev结构体
       dev   设备号
       count  cdev结构体的数量
 返回值:成功 0
         失败 负数

 3)将cdev结构体从内核链表中移除
 函数原型:void cdev_del(struct cdev *p) 
 参数:p  cdev结构体

 
设备节点

 手动创建: mknod  /dev/xxx c 主设备号 次设备号
 主、次设备号和驱动中的注册的设备号一致,将设备节点和设备关联
 设备节点被创建在内存上,系统重启,节点删除

 
如何实现设备操作
 
 应用程序:
     int fd;
     fd = open();
     //操作代码
     close(fd);
     
 驱动:
     int test_open(struct inode *, struct file *){
            //实现硬件设备打开操作
            return 0;
     }

     int test_close(struct inode *, struct file *){
           //实现硬件设备关闭操作
           return 0;
     }
     struct file_operations fops = {
         .open = test_open,
         .release = test_close,
     };

     
    
十三、
驱动如何操作硬件设备
应用程序:int ioctl(int d, int request, ...);
           功能:控制设备
           参数:d  文件描述符
                 request  命令码
                 ...     实现数据的传递
                 
                 #define _IO(type幻数,nr编号)        
                 #define _IOR(type,nr,size传输数据的大小)  
                 #define _IOW(type,nr,size)  
                 #define _IOWR(type,nr,size) 
                 
            返回值:成功  0
                    失败  -1
                    
 驱动:long test_ioctl(struct file *filep, unsigned int cmd, unsigned long arg(地址)){
                // 实现对设备的控制
                
        }
 
       struct file_operations fops = {
            .unlocked_ioctl = test_ioctl,
       }

       
硬件控制:

物理地址----------》虚拟地址
           映射
           
        函数原型: void  *ioremap(unsigned long offset, unsigned long size)
        功能:物理地址转换为虚拟地址
        参数:offset 物理地址 
        size:范围
        返回值: 成功  虚拟地址
                 失败  NULL
            
        函数原型:void iounmap(volatile void_iomemd *adr)    
        参数: adr 虚拟地址

        函数原型:u32 readl(const  void  *addr)
        功能:读取寄存器保存的值
        参数: addr 地址 (寄存器所在的地址)    ---虚拟地址
        返回值: 成功 寄存器的值
        
        函数原型:void writel(u32 b, volatile void __iomem *addr)
        功能:将修改之后的寄存器的值,写到寄存器
        参数:b   修改之后的值
        addr   寄存器所在的地址
        


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

嵌入式基础常识 的相关文章

  • 套接字发送并发保证

    如果我在两个进程 或两个线程 之间共享一个套接字 并且在这两个进程中我尝试发送一条阻塞的大消息 大于下划线协议缓冲区 是否可以保证这两个消息将按顺序发送 或者消息可以在内核内部交错吗 我主要对 TCP over IP 行为感兴趣 但了解它是
  • bash 或 sh 中的“=”和“==”运算符有什么区别

    我意识到 和 运算符都可以在 if 语句中使用 例如 var some string if var some string then doing something fi if var some string then doing some
  • 模拟用户输入以使用不同参数多次调用脚本

    我必须使用提供的脚本 该脚本在脚本运行时接受用户输入而不是参数 我无法解决这个问题 脚本的一个例子是 bin bash echo param one read one doSomething echo param two read two
  • 从命名管道读取

    我必须实现一个 打印服务器 我有 1 个客户端文件和 1 个服务器文件 include
  • 从 Java 读取 /dev/input/js0

    我正在尝试阅读 dev input js0来自Java 但我不断得到 java io IOException Invalid argument at java io FileInputStream read0 Native Method a
  • 编译器 libstdc++ 版本与系统版本

    我试图了解 g 如何选择它链接的 libstdc 版本 以及当库的 系统 版本不同时它意味着什么 我正在使用 gcc g 4 1 2 根据ABI 指南 http gcc gnu org onlinedocs libstdc manual a
  • 页面错误陷阱的成本

    我有一个应用程序 它定期 每 1 或 2 秒后 通过分叉自身来获取检查点 因此 检查点是原始进程的一个分支 它一直保持空闲状态 直到原始进程发生某些错误时被要求启动 现在我的问题是fork的写时复制机制的成本有多大 每当原始进程写入内存页面
  • 使用 gatttool 或 bluepy BLE 订阅通知

    我正在使用 bluepy 编写一个程序 用于监听蓝牙设备发送的特征 我还可以使用任何库或语言 唯一的限制是在 Linux 上运行 而不是在移动环境中运行 似乎仅在移动设备中广泛使用 没有人在桌面上使用 BLE 使用 bluepy 我注册了委
  • 使用 linux perf 工具测量应用程序的 FLOP

    我想使用 perf Linux 性能计数器子系统的新命令行接口命令 来测量某些应用程序执行的浮点和算术运算的数量 出于测试目的 我使用了我创建的一个简单的虚拟应用程序 请参见下文 因为我找不到任何为测量 FP 和整数运算而定义的 perf
  • 代码::块 - 警告:GDB:无法设置控制终端:不允许操作

    我已经通过官方存储库在 Ubuntu 14 04 中安装了 Code Blocks 13 12 当我编译时 一切正常 但是当我调试时 shell 中会显示以下消息 警告 GDB 无法设置控制终端 操作不正确 允许的 程序执行到断点 但当我执
  • 如何从脚本向 sudo 提供密码?

    请注意 这是在我的本地计算机上运行的来宾虚拟机 VBox 我不担心安全性 我正在编写一个将在 Linux Ubuntu VM 上执行的脚本myuser用户 该脚本将在下面创建一个非常大的目录树 etc myapp 目前我必须手动完成所有这些
  • sed 仅最后一个匹配模式

    我想sed仅文本文件的最后一个匹配模式 输入文件 boy boy girl boy 输出文件 boy boy girl boys 一种方法是反转文件 仅替换第一个匹配项 然后再次反转 tac
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • 在64位操作系统上以32位模式和64位模式编译ioctl函数的执行有什么不同?

    我有 64 位 Enterprise SuSE 11 我有一个应用程序 它打开 HIDRAW 设备并在其上操作 ioctl 函数以从该设备获取原始信息 如下所示 struct hidraw devinfo devinfo int fd op
  • Mono 和 WebRequest 速度 - 测试

    在 mono 4 6 2 linux 中 我注意到 wget 下载文件的速度与webclient DownloadString 所以我做了一个小测试来调查 为什么 wget 明显比 C 快 根据我自己的实验 使用 wget 下载 手动读取文
  • 为什么使用Python的os模块方法而不是直接执行shell命令?

    我试图了解使用Python的库函数执行特定于操作系统的任务 例如创建文件 目录 更改文件属性等 背后的动机是什么 而不是仅仅通过执行这些命令os system or subprocess call 例如 我为什么要使用os chmod而不是
  • jpackage linux 创建的桌面文件不足

    我刚刚开始使用 jpackage 它是一个非常棒的工具 只要迈出一步 我的肩上的工作就减轻了很多 我对看起来硬编码且无法定制的东西越感到惊讶 JPackage 自动生成启动器 lib
  • xdotool 类型需要很长时间并导致整个桌面冻结

    我一直在使用xdotool type过去只能在快捷方式上输入耸肩xdotool type 这可行 但总是需要相当长的时间 并导致整个桌面冻结 完全冻结 而不仅仅是输入 几秒钟 不过并没有太打扰我 现在我需要一种方法来从文件中读取内容 对其进
  • 在 Ubuntu 上纯粹通过 bash 脚本安装 mysql 5.7

    我想要一个无需任何手动输入即可安装 MySQL 5 7 实例的 bash 脚本 我正在关注数字海洋教程 https www digitalocean com community tutorials how to install mysql
  • 静态链接共享对象?或者损坏的文件?

    我有一个从专有来源获得的库 我正在尝试链接它 但出现以下错误 libxxx so 文件无法识别 文件格式无法识别 Collect2 ld 返回 1 退出状态 确实 ldd libxxx so statically linked 这究竟意味着

随机推荐

  • Doris节点扩容及数据表

    扩容和缩容 上篇文章简单讲了doris的安装 本章分享的是doris中fe和be节点的扩容缩容以及doris的数据表 1 FE 扩容和缩容 使用 MySQL 登录客户端后 可以使用 sql 命令查看 FE 状态 目前就一台 FE mysql
  • git学习心得

    git是一款十分有用的版本控制软件 程序员必备 http www liaoxuefeng com wiki 0013739516305929606dd18361248578c67b8067c8c017b000 001374325691607
  • LeetCode第79题:单词搜索

    给定一个 m x n 二维字符网格 board 和一个字符串单词 word 如果 word 存在于网格中 返回 true 否则 返回 false 单词必须按照字母顺序 通过相邻的单元格内的字母构成 其中 相邻 单元格是那些水平相邻或垂直相邻
  • 中国人民大学计算机系孙辉,张静(中国人民大学信息学院计算机系讲师)_百度百科...

    张静 中国人民大学信息学院计算机系讲师 语音 编辑 锁定 讨论 上传视频 本词条缺少概述图 补充相关内容使词条更完整 还能快速升级 赶紧来编辑吧 张静 现任中国人民大学信息学院计算机系讲师 1 中文名 张静 毕业院校 比利时鲁汶大学学位 学
  • 最详细的Java知识点--Map集合

    Map 主要内容 Map集合 目标 能够说出Map集合特点 使用Map集合添加方法保存数据 使用 键找值 的方式遍历Map集合 使用 键值对 的方式遍历Map集合 能够使用HashMap存储自定义键值对的数据 能够使用HashMap编写斗地
  • java错误和异常

    错误 error 非常严重 不处理无法编译 不过很容易处理 一般也就是变量名错误 函数写错了这些 还有就是内存 环境问题了 异常 Exception 编译时异常 必须使用try catch才能运行 比如IOException SQLExce
  • Java--- Java 中的线程,一般执行完成后就会自动销毁

    关于 Java 中的线程 一般执行完成后就会自动销毁 程序会终止 如下测试代码 public class Test implements Runnable public static void main final String args
  • Unity 2D 碰撞检测位置,生成烟雾实例化

    ContactPoint2D contact p collision contacts 0 Quaternion rot Quaternion FromToRotation Vector3 up contact normal Vector3
  • ubuntu安装最新版docker简易教程

    Ubuntu Docker 安装 Docker Engine Community 支持以下的 Ubuntu 版本 Xenial 16 04 LTS Bionic 18 04 LTS Cosmic 18 10 Disco 19 04 其他更新
  • pyecharts源码解读(17)HTML组件包components之表格组件Table

    当前pyecharts的版本为1 9 0 components包概述 components包位于pyecharts包顶级目录中 用于定义pyecharts的HTML组件 包结构如下 components HTML组件包 image py 定
  • python注意事项2

    工具pycharm 1 字符串的方法 hello str hello world 以什么开始 hello str startwith h 以什么结束 hello str endwith 去除空白字符 string lstrip 去除左边的空
  • 【Docker网络】Docker的容器互联

    Docker网络 Docker的容器互联 一 Docker容器互联介绍 1 1 Docker容器互联简介 1 2 Docker容器互联方式 二 本次实践介绍 2 1 本地环境规划 2 2 本次实践介绍 三 默认网络下的容器互联 3 1 默认
  • ABB PFEA111-20 3BSE050090R20处理器模块

    处理能力 PFEA111 20 处理器模块可能具备高性能的处理能力 能够执行复杂的控制算法 逻辑运算和数据处理任务 多通道输入输出 该模块可能会提供多个数字或模拟输入通道 用于监测外部信号 以及多个输出通道 用于控制执行器和设备 通信接口
  • 测试自动化面试题

    Python python有哪些数据类型 Python支持多种数据类型 包括以下常见的数据类型 数字类型 整数 int 浮点数 float 和复数 complex 字符串类型 由字符组成的不可变序列 使用引号 单引号或双引号 括起来 列表
  • 机器学习(三)K-means聚类(手肘法、轮廓系数、可视化代码)

    K means聚类 聚类是无监督学习当中非常重要的一部分 能够在没有标签的情况下将数据分类 说到聚类 最常用也是最重要的一个算法就是K means算法 算法介绍 K means是一种非常简单快速高效的算法 只需要迭代几次即可 其原理用一句话
  • linux---"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message

    2020年3月14日服务器异常重启 查看 var log message日志 如下 Mar 14 15 04 59 localhost kernel azx single send cmd 11 callbacks suppressed M
  • GLES3.0中文API-glGetProgramResource

    名称 glGetProgramResource 检索程序对象中单个活动资源的多个属性的值 C 规范 void glGetProgramResourceiv GLuint program GLenum programInterface GLu
  • flask模块mock接口(一)

    目录 一 安装第三方模块 二 flask模块的使用 三 动态路由 四 返回json格式数据 有时候测试需要调用第三方接口进行测试 但是第三方接口没有提供时 我们可以通过mock接口模拟第三方接口 一 安装第三方
  • UNITY3D 实现暂停(Coroutine)

    前断时间在做一个游戏项目 为了实现暂停还有游戏逻辑中用yield 自己写了一个类 代码如下 using UnityEngine using System Collections if want gameobject pause Updata
  • 嵌入式基础常识

    一 基本概念 linux ubuntu 用户名 类型 普通用户 系统名称 家目录 root 管理员用户 pwd 显示当前工作路径 绝对路径 home linux 家目录 根目录下 代表根目录 ls 列出文件状态 选项 l i h 1 rwx