技术标签: linux嵌入式编程高手历程 脚本 linux makefile 编程 cmd 嵌入式
一uboot
1。uboot增加自己的命令
原理:
每个命令都有一个命令结构体
struct cmd_tbl_s {
char*name; /* Command Name*/
intmaxargs; /* maximum number of arguments*/
intrepeatable; /* autorepeat allowed?*/
int (*cmd)(struct cmd_tbl_s *, int, int, char *[]); /* Implementation function*/
char*usage;/* Usage message(short)*/
char*help;/* Help message(long)*/
};
去定义它。Cmd为要调用的命令函数!name为该命令名字符串。
在u-boot里面有这样的宏
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) /
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
宏U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)就是将
cmd_tbl_s{
name,
maxargs,
rep,
cmd,
usage,
help
}这样的一个命令结构体放入内存.u_boot_cmd这个区域,.u_boot_cmd这个域在board/smdk2410/u-boot.lds中定义!在U-boot中的shell中,根据用户输入的命令,就会在.u_boot_cmd这个内存区域中查找,当.u_boot_cmd中某一个cmd_tbl_s命令结构体的cmd_tbl_s.name和输入的命令字符串相符时,就调用该命令
结构体的cmd_tbl_s.cmd( ….)函数!
怎样添加命令函参数!
下面以添加USB下载命令为例!
a
在include/configs/smdk2410.h中的CONFIG_COMMDNDS中增加一项:
CFG_CMD_USBLOAD,
/***********************************************************
* Command definition
***********************************************************/
#define CONFIG_COMMANDS /
(CONFIG_CMD_DFL | /
CFG_CMD_CACHE | /
CFG_CMD_NET | /
CFG_CMD_ENV | /
CFG_CMD_FLASH | /
CFG_CMD_PING | /
CFG_CMD_NAND | /
/*CFG_CMD_EEPROM |*/ /
/*CFG_CMD_I2C |*/ /
/*CFG_CMD_USB |*/ /
CFG_CMD_REGINFO | /
CFG_CMD_DATE | /
CFG_CMD_USBLOAD |/
CFG_CMD_ELF)
b
在include/cmd_confdefs.h中加入命令标志位
#define CFG_CMD_USBLOAD0x00000055ULL (可以是其它值,不冲突就好)
c
在common/下面加入usbload.c
框架如下
#If(CONFIG_COMMANDS & CFG_CMD_USBLOAD)
Int usb_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[ ] )
{
………………….
}
U_BOOT_CMD{
Usbload,
2,
1,
usb_load,
“usb load img file”,
“This is a test”
};
#endif
d
在common/Makefile 添加要编译的目标文件
e
重新编译u-boot,就OK啦!
参考:http://www.cublog.cn/u/17660/showart.php?id=279308
2。uboot增加对gpio,mii phy寄存器的设置
二。文件系统
dhcpc和httpd在busybox的menuconfig中可以选择安装。但是,我们的busybox工具包是方案直接提供的,目前没有时间重头定制。因此选用了源代码交叉编译来得到。
1。busybox
下载busybox1.10.0
make menuconfig //选择需要安装的部件
make ARCH=mips CROSS_COMPILE=mips-linux- //交叉编译
make install
会出现一个_install目录,拷贝相应文件到文件系统中即可。
2。dhcpc
从busybox网站下载dhcpc包,http://udhcp.busybox.net/
交叉编译.拷贝至/sbin/
拷贝example下面的simple.script 至文件系统的/usr/share/udhcpc/,更改文件名字为default.script
如此系统启动的时候将自动运行dhcp来获取ip地址
3。boa。
1)下载Boa源码
下载地址: http://www.boa.org/, 或者http://sourceforge.net/:
boa-0.94.13.tar.gz,解压:# tar zxvf boa-0.94.13.tar.gz
2)生成Makefile文件
# cd boa-0.94.13
# src/configure
3)修改Makefile文件,编译
# cd boa-0.94.13/src
修改Makefile文件:修改 CC=gcc 为CC=/usr/local/arm/2.95.3/bin/arm-linux-gcc
修改 CPP=gcc -E为CPP=/usr/local/arm/2.95.3/bin/arm-linux-gcc –E
make
在编译时有可能会提示查不到“yacc”
# mips-linux-strip boa
4)boa的配置
进入制作的根文件夹
# mkdir /etc/boa
# cp / boa-0.94.13/boa.conf /etc/boa/
修改boa.conf:
1、 Group的修改:修改 Group nogroup 为Group 0
由于在/etc/group文件中没有nogroup组,所以设成0。另外在/etc/passwd中有nobody用户,所以User nobody不用修改。
2、scriptAlias的修改:修改 scriptAlias /cgi-bin/ /usr/lib/cgi-bin/
为 scriptAlias /cgi-bin/ /var/www/cgi-bin/
3、ServerName的设置:修改 #ServerName http://www.your.org.here/
为 ServerName http://www.your.org.here/
注意:该项默认为未打开,执行Boa会异常退出,提示“gethostbyname::No such file or directory”,所以必须打开。其它默认设置即可。
5)boa的执行
进入制作的根文件夹
# mkdir /var/log
# mkdir /var/log/boa(创建日志文件目录)
# mkdir /var/www (创建HTML文档的主目录)
可以将主机 /usr/share/doc/HTML/目录下的index.html文件和img目录复制到/var/www目录下,将主机/etc目录下的mime.types文件放置到制作的根文件夹的/etc下
最后将boa-0.94.13下的boa可执行文件拷贝到bin下面。
参考:http://www.linuxidc.com/Linux/2007-09/7697.htm
4.thttpd
从http://www.acme.com/software/thttpd/ 下载thttpd
./configure
vi Makefile
CC= mips-linux-gcc
make ARCH=mips CROSS_COMPILE=mips-linux-
配置
拷贝thttpd二进制可执行文件到根文件系统/root/目录中
修改thttpd配置文件
vi thttpd.conf
# This section overrides defaults
dir=/www #指明WebServer存放网页的根目录路径
chroot
user=root #以root身份运行thttpd
logfile=/var/log/thttpd.log #日志文件路径
pidfile=/var/run/thttpd.pid #pid文件路径
port=8080
拷贝thttpd.conf配置文件到根文件系统的/etc/目录,
执行:/root/thttpd -C /et/thttpd.conf
参考: http://blog.csdn.net/zhulingchen/archive/2007/02/02/1501134.aspx
5.busybox自带的httpd
使用了busybox自带的httpd之后,boa以及thttpd都被我扫进了历史的垃圾堆
参考:http://pank.org/blog/2003/08/busybox-10-httpd.html
基本用法: httpd -h /documentroot -c /etc/httpd.conf
一句话,搭建httpd太方便了
如果网页需要认证,在/etc/httpd.conf里加入:
/:admin:adminpass
三 busybox
1。向 BusyBox 中添加新命令
向 BusyBox 添加一个新命令非常简单,这是因为它具有良好定义的体系结构。第一个步骤是为新命令的源代码选择一个位置。我们要根据命令的类型(网络,shell 等)来选择位置,并与其他命令保持一致。这一点非常重要,因为这个新命令最终会在 menuconfig 的配置菜单中出现(在下面的例子中,是 Miscellaneous Utilities 菜单)。
对于这个例子来说,我将这个新命令称为 newcmd,并将它放到了 ./miscutils 目录中。这个新命令的源代码如清单 13 所示。
清单 1. 集成到 BusyBox 中的新命令的源代码
#include "busybox.h" int newcmd_main( int argc, char *argv[] ) { int i; printf("newcmd called:/n"); for (i = 0 ; i < argc ; i++) { printf("arg[%d] = %s/n", i, argv[i]); } return 0; } |
接下来,我们要将这个新命令的源代码添加到所选子目录中的 Makefile.in 中。在本例中,我更新了 ./miscutils/Makefile.in 文件。请按照字母顺序来添加新命令,以便维持与现有命令的一致性:
清单 2. 将命令添加到 Makefile.in 中
MISCUTILS-$(CONFIG_MT) += mt.o MISCUTILS-$(CONFIG_NEWCMD) += newcmd.o MISCUTILS-$(CONFIG_RUNLEVEL) += runlevel.o |
接下来再次更新 ./miscutils 目录中的配置文件,以便让新命令在配置过程中是可见的。这个文件名为 Config.in,新命令是按照字母顺序添加的:
清单 3. 将命令添加到 Config.in 中
config CONFIG_NEWCMD bool "newcmd" default n help newcmd is a new test command |
这个结构定义了一个新配置项(通过 config 关键字)以及一个配置选项(CONFIG_NEWCMD)。新命令可以启用,也可以禁用,因此我们对配置的菜单属性使用了 bool (Boolean)值。这个命令默认是禁用的(n 表示 No),我们可以最后放上一个简短的 Help 描述。在源代码树的 ./scripts/config/Kconfig-language.txt 文件中,我们可以看到配置语法的完整文法。
接下来需要更新 ./include/applets.h 文件,使其包含这个新命令。将下面这行内容添加到这个文件中,记住要按照字母顺序。维护这个次序非常重要,否则我们的命令就会找不到。
清单 4. 将命令添加到 applets.h 中
USE_NEWCMD(APPLET(newcmd, newcmd_main, _BB_DIR_USER_BIN, _BB_SUID_NEVER)) |
这定义了命令名(newcmd),它在 Busybox 源代码中的函数名(newcmd_main),应该在哪里会为这个新命令创建链接(在这种情况中,它在 /usr/bin 目录中),最后这个命令是否有权设置用户 id(在本例中是 no)。
倒数第二个步骤是向 ./include/usage.h 文件中添加详细的帮助信息。正如您可以从这个文件的例子中看到的一样,使用信息可能非常详细。在本例中,我只添加了一点信息,这样就可以编译这个新命令了:
清单 5. 向 usage.h 添加帮助信息
#define newcmd_trivial_usage "None" #define newcmd_full_usage "None" |
最后一个步骤是启用新命令(通过 make menuconfig,然后在 Miscellaneous Utilities 菜单中启用这个选项)然后使用 make 来编译 BusyBox。
使用新的 BusyBox,我们可以对这个新命令进行测试,如清单 18 所示。
清单 6. 测试新命令
$ ./busybox newcmd arg1 newcmd called: arg[0] = newcmd arg[1] = arg1 $ ./busybox newcmd --help BusyBox v1.1.1 (2006.04.12-13:47+0000) multi-call binary Usage: newcmd None None |
就是这样!BusyBox 开发人员开发了一个优秀但非常容易扩展的工具。
参考:http://www.xxlinux.com/linux/article/development/embed/20060918/4364.html
2。完善文件系统
参考一个正常的Linux系统就会发现,busybox建立的文件系统还缺少很多文件。下面三行命令建立了常见UNIX系统中包含的一些目录,虽然它们不全是必需的,但建立它们更符合标准一些。这些命令都是在新文件系统的根目录中执行的,第三条命令的执行还必须要有root权限。mkdir mnt root var tmp proc boot etc lib
mkdir /var/{lock,log,mail,run,spool}
chown 0:0R *如果busybox采用了动态链接的方式编译,还需要把busybox所需要的动态库:libcrypt.so.1、libc.so.6、ldlinux.so.2放到lib目录中。最好按照标准的方式建立相应的文件和链接,可以参考下面的列表:-rwxrwxrwx 192519ld-2.3.2.so
lrwxrwxrwx 111ld-linux.so.2 -> ld-2.3.2.so
-rwxrwxrwx 1 1190032libc-2.3.2.so
lrwxrwxrwx 113libc.so.6 -> libc-2.3.2.so
-rwxr-xr-x 118348libcrypt-2.3.2.so
lrwxrwxrwx 117libcrypt.so.1 -> libcrypt-2.3.2.so3.2编写 etc文件夹下的文件
etc文件夹是许多系统配置文件保存的地方。这些文件非常重要,如果配置错误,就可能影响系统的启动。busybox源代码example/bootfloopy/etc目录中的文件算是一个简单的例子,可以把其中的文件拷贝过来作为基础。(在example/bootfloopy目录中的一些脚本和文档也很值得阅读)
首先inittab文件是系统启动后所访问的第一个脚本文件,后续启动的文件都由它指定。这个文件的格式和普通微机Linux上的inittab是有区别的,其具体含义可以参考busybox的文档。下面是一个比较简单的例子:::sysinit:/etc/init.d/rcS
tty0::respawn:/sbin/getty 38400 tty0
tty2::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount ar
::shutdown:/bin/mount / o remount,ro其中第一行指定了系统的启动脚本为/etc/init.d/rcS;第二行指定在第一个虚拟终端打开一个登录会话;第三行指定在第三个虚拟终端打开一个无须登录验证的shell;第四行指定了当按下ctrl+alt+del组合键时的执行命令;最后两行指定了关机时执行的操作。
fstab文件定义了文件系统的各个“挂接点”,需要与实际的系统相配合。一个简单的fstab文件如下:proc/procprocdefaults00
/dev/hda1/ext2rw,noauto01
devpts/dev/ptsdevptsdefaults00其中第三行是为UNIX PTYs准备的,telnetd要用到。
profile文件是终端登录之后首先运行的脚本,这里可以不去管它。我们比较关心的是系统在无人登录的情况下有哪些程序要执行。从inittab文件可以看出系统启动之后要运行/etc/init.d/rcS脚本,需要启动的程序和需要进行的设置都可以写在这里面。一个可能的rcS文件如下:#! /bin/sh
echo e 'Starting System'
ifconfig lo 127.0.0.1
ifconfig eth0 192.168.0.100
hostname F /etc/hostname
/bin/mount / o remount,rw
/bin/mount /proc
/bin/mount /dev/pts
/usr/sbin/telnetd
dmesg > /var/log/dmesg为了满足终端登录用户验证的要求,etc目录下还需要有passwd、group和shadow (在编译busybox时如果不选择shadow功能将不需要这个文件)。这些文件至少要包含 root用户的定义,如下所示:passwd:
root:x:0:0:root:/root:/bin/sh
group:
root:x:0:
shadow:
root::12179:0:99999:7:::其中,如果shadow (对于不支持shadow的系统则是passwd )文件的第一个冒号和第二个冒号之间没有内容,表示这个用户登录不需要密码。如果需要设定密码或者增加新的登录用户,就可以参考开发主机上的相应文件,或者在目标系统启动之后用passwd命令和adduser命令完成。
最后还可以给目标机起一个名字,在/etc目录下建立文件hostname,将起好的名字写到里面。前面介绍的启动脚本rcS,通过hostname命令把文件的内容设置为机器名。
文件系统的安装随着应用环境的不同差别比较大。在嵌入式环境中,一般只要通过特殊的打包工具将文件系统打包,并烧录到非易失性存储器中就可以了。例如,对于JFFS2类型的文件系统就可以用mkfs.jffs2命令生成文件系统的映像。
文件系统安装之后重新启动目标设备,应该就可以使用新建立的文件系统了。如果系统启动失败,则可以通过内核消息查找错误的原因。如果错误信息提示不能正确挂载文件系统,问题可能出在启动引导装载程序(bootloader)上。文件系统比较容易出问题的是用户的验证和动态链接库的加载。最简单的检测办法是把busybox编译为静态链接并设置内核参数init=/bin/sh来躲开对用户登录的验证。
3。linux的启动
Linux有自己一套完整的启动体系,抓住了linux启动的脉络,linux的启动过程将不再神秘。我们可以按需要来手动添加和删除我们需要的应用服务。
本文中假设inittab中设置的init tree为:
/etc/rc.d/rc0.d
/etc/rc.d/rc1.d
/etc/rc.d/rc2.d
/etc/rc.d/rc3.d
/etc/rc.d/rc4.d
/etc/rc.d/rc5.d
/etc/rc.d/rc6.d
/etc/rc.d/init.d
1). 关于linux的启动
init是所有进程之父
init读取/etc/inittab,执行rc.sysinit脚本
(注意文件名是不一定的,有些unix甚至会将语句直接写在inittab中)
rc.sysinit脚本作了很多工作:
init $PATH
config network
start swap function
set hostname
check root file system, repair if needed
check root space
....
rc.sysinit根据inittab执行rc?.d脚本
linux是多用户系统,getty是多用户与单用户的分水岭
在getty之前运行的是系统脚本
2). 关于rc.d
所有启动脚本放置在 /etc/rc.d/init.d下
rc?.d中放置的是init.d中脚本的链接,命名格式是:
S{number}{name}
K{number}{name}
S开始的文件向脚本传递start参数
K开始的文件向脚本传递stop参数
number决定执行的顺序
3). 启动脚本示例
这是一个用来启动httpd的 /etc/rc.d/init.d/apache 脚本:
CODE: #!/bin/bash source /etc/sysconfig/rc source $rc_functions case "$1" in start) echo "Starting Apache daemon..." /usr/local/apache2/bin/apachectl -k start evaluate_retval ;; stop) echo "Stopping Apache daemon..." /usr/local/apache2/bin/apachectl -k stop evaluate_retval ;; restart) echo "Restarting Apache daemon..." /usr/local/apache2/bin/apachectl -k restart evaluate_retval ;; status) statusproc /usr/local/apache2/bin/httpd ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac [Copy to clipboard] |
然后可以这样建立rc?.d的链接:
CODE: cd /etc/rc.d/init.d && ln -sf ../init.d/apache ../rc0.d/K28apache && ln -sf ../init.d/apache ../rc1.d/K28apache && ln -sf ../init.d/apache ../rc2.d/K28apache && ln -sf ../init.d/apache ../rc3.d/S32apache && ln -sf ../init.d/apache ../rc4.d/S32apache && ln -sf ../init.d/apache ../rc5.d/S32apache && ln -sf ../init.d/apache ../rc6.d/K28apache [Copy to clipboard] |
经常使用的 rc.local 则完全是习惯问题,不是标准。
各个发行版有不同的实现方法,可以这样实现:
CODE: touch /etc/rc.d/rc.local chmod +x /etc/rc.d/rc.local ln -sf /etc/rc.d/rc.local /etc/rc.d/rc1.d/S999rc.local && ln -sf /etc/rc.d/rc.local /etc/rc.d/rc2.d/S999rc.local && ln -sf /etc/rc.d/rc.local /etc/rc.d/rc3.d/S999rc.local && ln -sf /etc/rc.d/rc.local /etc/rc.d/rc4.d/S999rc.local && ln -sf /etc/rc.d/rc.local /etc/rc.d/rc5.d/S999rc.local && ln -sf /etc/rc.d/rc.local /etc/rc.d/rc6.d/S999rc.local [Copy to clipboard] |
/etc/profile
/etc/bashrc
~/.bash_profile
~/.bashrc
是bash的启动脚本
一般用来设置单用户的启动环境,也可以实现开机单用户的程序,但要明确他们都是属于bash范畴而不是系统范畴。
他们的具体作用介绍如下:
/bin/bash这个命令解释程序(后面简称shell)使用了一系列启动文件来建立一个运行环境:
/etc/profile
/etc/bashrc
~/.bash_profile
~/.bashrc
~/.bash_logout
每一个文件都有特殊的功用并对登陆和交互环境有不同的影响。
/etc/profile 和 ~/.bash_profile 是在启动一个交互登陆shell的时候被调用。
/etc/bashrc 和 ~/.bashrc 是在一个交互的非登陆shell启动的时候被调用。
~/.bash_logout 在用户注销登陆的时候被读取
一个交互的登陆shell会在 /bin/login 成功登陆之后运行。一个交互的非登陆shell是通过命令行来运行的,如[prompt]$/bin/bash。一般一个非交互的shell出现在运行shell脚本的时候。之所以叫非交互的shell,是因为它不在命令行上等待输入而只是执行脚本程序。
6). 关于开机程序的自动启动
系统脚本可以放置在/etc/rc.d/init.d中并建立/etc/rc.d/rc?.d链接,也可以直接放置在/etc/rc.d/rc.local中。
init.d脚本包含完整的start,stop,status,reload等参数,是标准做法,推荐使用。
为特定用户使用的程序(如有的用户需要使用中文输入法而有的不需要)放置在~/中的bash启动脚本中。
参考:http://www.51cto.com/art/200707/52340.htm
四。利用BusyBox做一个简单的根文件系统
1、下载BusyBox源代码包 http://busybox.net/
2、找个地方解压缩包,例如tar -xjvf busybox-1.00.tar.bz2
3、进入busybox的文件夹,使用make menuconfig进入设置
4、在build options中有一些选项要注意
Build BusyBox as a static binary (no shared libs):如果选择了这个选项,那么BusyBox将被静态编译,也就是不需要动态链接库的支持就能运行,但是这样会使编译后文件的体积增大。
Do you want to build BusyBox with a Cross Compiler:如果你的busybox将要运行机器与编译主机的体系结构不同,比如s3c2410是ARM,与我们的X86主机芯片系统结构不一样,那么这个一定要选上,并且在 Cross Compiler prefix中写上交叉编译器的名字,比如ARM用arm-linux-
5、在Installation Options中 BusyBox installation prefix就是在编译完后运行make install 时,busybox将被安装的地址。
6、其它的选项按照默认选项就行,当然自己也可以看看有没有需要,把其它一些命令加入到编译选项中来
7、完成后保存,然后运行make
8、编译没有问题后运行make install这样编译好的busybox就会自动安装到BusyBox installation prefix中,一般是三个文件夹bin sbin usr和一个文件linuxrc。这样busybox的编译就完成了
9、准备一个空文件夹将BusyBox installation prefix中的东西拷过来,另外再建几个linux需要的文件夹
lib
dev
etc
home
proc
root
tmp
var
mnt
10、在etc文件夹下建一个目录init.d,并且在其中建立一个空文件rcS,在rcS中加上以下内容
#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
#
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
trap ":" INT QUIT TSTP
/bin/mount -t proc none /proc
11、如果你的busybox是静态编译的,那么一个简单的能使用的根文件系统就这样完成了,但是这个文件系统中没有glibc的动态链接库,除了busybox以外的软件,如果对glibc有依赖,但是又没有静态编译的的话就无法运行。但如果所有的软件都用静态编译的话,那这个文件系统将很大。所以一般推荐软件不要使用静态编译,而使用一个库。
12、如果你不是用静态编译的,那么你需要编译好的glibc的动态链接库。在一般的交叉编译器中都带有已经编译好的库,直接拷过来就行了。
出现Warning: unable to open an initial console.提示,可以在rmadisk中建立
建立console和null试试,不一定非要去修改内核中的devfs去动态创建
cd /dev
mknod -m 660 console c 5 1
mknod -m 660 null c 1 3
文章浏览阅读5.9k次,点赞3次,收藏16次。因为Ubuntu20.04比较新,而Mysql5.6比较老,所以这两者之间的支持不太好。也不知道是服务器本身就有啥问题,还是两者软件的支持不足,我在安装Mysql5.6的时候遇到了很多困惑和问题。2.1 彻底卸载MYSQL因为不清楚服务器的具体状况,前面也实验了很多次都失败了,所以要先彻底的清除Mysql,然后再进行后续的安装。第一,使用命令dpkg --list|grep mysql查看跟Mysql相关的包。第二,首先卸载common包。sudo apt-get remove mysq.._ubuntu安装mysql5.6
文章浏览阅读309次。OpenGL 变换我们现在知道如何创建对象,为它们着色或使用赋予它们一个详细的外观,但它们仍然没有那么有趣,因为它们都是静态对象。我们可以尝试通过更改其顶点并重新配置每个帧的缓冲区来移动它们,但这很麻烦,并且需要相当多的处理能力。有更好的方法来转换对象,这是通过使用(多个)矩阵对象。矩阵是非常强大的数学结构,起初看起来很可怕,但一旦你习惯了它们,它们将被证明是非常有用的。在讨论矩阵时,我们将不得不深入研究一些数学知识。然而,要充分理解变换,我们首先必须在讨论矩阵之前深入研究向量。本章的重点是为您提供我_沿y轴旋转矩阵 glsl
文章浏览阅读112次。yaml-cpp库 是一个功能强大的 C++ 库,用于处理 YAML 数据格式。其源码结构清晰,模块划分合理,易于理解和扩展。库内提供了丰富的 API,包括节点的创建、查询、修改以及文件的读写等,使得开发者能够方便地在 C++ 中操作 YAML 数据。源码中使用了现代 C++ 特性,如模板元编程和智能指针,保证了代码的安全性和效率。此外,yaml-cpp 还具有良好的异常处理和错误报告机制,使得开发者能够轻松应对各种异常情况。_windows 添加yaml-cpp
文章浏览阅读107次。因为项目需求的更新,最近一直在做将裸机项目移植成RTOS,准备记录这个过程,慢慢尝试,慢慢总结。_iot 实践学习
文章浏览阅读334次。京东旗舰店商品数据分析接口,京东旗舰店商品详情接口,京东旗舰店商品销量接口,京东旗舰店商品列表接口,京东旗舰店商品sku接口,京东旗舰店商品详情采集接口,京东旗舰店商品销量采集,京东旗舰店商品评论采集接口,京东商品详情接口,京东关键词搜索商品接口,京东商品列表接口,京东旗舰店总销量接口,京东旗舰店商品总销量接口,京东旗舰店商品列表接口,京东旗舰店店铺分析商品接口,京东旗舰店商品采集接口,京东商品详情API接口,京东旗舰店商品详情API接口_京东商品详情页接口分析
文章浏览阅读7次。Lua 在内部发生异常时,VM 会在 C 的 stack frame 上直接跳至之前设置的恢复点,然后 unwind lua vm 层次上的 lua stack。上面这段话的意义在于在 Lua 中使用 C++ 异常,如果 Lua 抛出异常,此时走 C++ 异常机制,可确保对象被正确销毁,即析构函数被调用,也就保证了 RAII 机制。总之,要小心处理 Lua 中的异常,特别是在 C++ 中。在 C++ 中,即使 Lua 中的异常使用了 C++ 异常,要捕获 Lua 中抛出的异常,也只能通过。
文章浏览阅读69次。C代表的过程性语言以类为代表的面向对象语言C++模板支持的泛型编程。
文章浏览阅读1.2k次,点赞31次,收藏21次。torchvision是PyTorch项目的一部分,由流行数据集,模型结构和计算机视觉的常见图像变换构成。这篇文章介绍第一个部分,数据集部分。
文章浏览阅读502次。一般情况下,lambda函数的语法定义如下:[capture] (parameters)mutable->{statement}[capture] :捕获列表,捕获列表出现在lambda函数的起始处,[]也被称为lambda的引出符,编译器根据引出符判断接下来的代码是否是lambda函数。(parameters) :参数列表,跟普通函数参数列表一致,当不传递参数时,可省略。mutable:默认情况下,lambda函数是const函数,当lambda函数使用值传递时,mutable。_std::thread lambda mutable
文章浏览阅读810次。相关阅读:1. Java研发方向如何准备BAT技术面试(超级干货)2. 超实用的——BAT面试技巧这篇文章是针对文章《 Java研发方向如何准备BAT技术面试(超级干货)》里面的Java基础问题的一些答案。如有错误,还请各位网友指正。多谢!!!文章首发地址为微信公众号:猿blog 文章首发地址为微信公众号:猿blog 文章首发地址为微信公众号:猿blog重要的事情说三遍!!! 更多干货文章,_java研发方向如何准备bat技术面试关注微信公众号:猿blog关注微信公众号:猿blog关
文章浏览阅读501次,点赞8次,收藏8次。Q-learning是一种强化学习算法,用于解决基于奖励的决策问题。它是一种无模型的学习方法,通过与环境的交互来学习最优策略。Q-learning的核心思想是通过学习一个Q值函数来指导决策,该函数表示在给定状态下采取某个动作所获得的累积奖励。Q-learning的训练过程如下:1. 初始化Q值函数,将所有状态-动作对的Q值初始化为0。2. 在每个时间步,根据当前状态选择一个动作。可以使用ε-greedy策略来平衡探索和利用。3. 执行选择的动作,并观察环境返回的奖励和下一个状态。_qlearning求解旅行商问题tsp python
文章浏览阅读1.7k次,点赞3次,收藏8次。算法流程:优缺点其他改进算法_减法聚类