如何将镜像烧写至iNand(fastboot命令的源码分析)

以下内容源于网络资源的学习与整理,如有侵权请告知删除。

参考博客

u-boot sdfuse命令烧录分析----从SD卡加载内核_white_bugs的博客-CSDN博客

一、将镜像文件烧写至iNand的步骤

步骤1:完成准备工作。

(1)准备fastboot相关软件包。

fastboot在windows端的软件包、fastboot在windows端的驱动包。

(2)用usb转otg数据线连接电脑和开发板。

(3)正确安装fastboot的驱动。

在uboot控制台输入fastboot,如果尚未安装驱动,在windows端的设备管理器相应项目下会显示问号(或感叹号),此时选中该项目,右键选择属性,选择更新驱动程序,然后选择驱动包所在的路径,勾选“包括子文件夹”,点击下一项即可。

正确安装fastboot驱动之后显示的内容如下:

(4)准备好待烧录的镜像文件。

假如要烧录linux内核镜像文件、QT4.8文件系统镜像、uboot镜像。相关镜像文件在开发板资料的X210V3S_B\linux\QT4.8目录中,账号与密码分别是root、123456。

为了操作方便,这里将镜像文件和fastboot软件包的内容放在同一目录。

步骤2:在uboot控制台下输入命令fastboot。

步骤3:开始烧写uboot、内核以及根文件系统镜像

(1)在window命令窗口中切换到fastboot软件包所在的路径。

(2)输入“fastboot devices”查看是否有设备,没有不能进行下一步内容。

(3)利用“fastboot flash inand的分区 镜像文件路径”命令烧写各个镜像文件。

1)烧录uboot镜像文件

在windows端输入“fastboot flash bootloader uboot.bin”时,windows控制台与uboot控制台显示内容如下。

C:\Users\34316\Desktop\fastboot>fastboot flash bootloader uboot.bin
sending 'bootloader' (384 KB)... OKAY
writing 'bootloader'... OKAY
Received 17 bytes: download:00060000
Starting download of 393216 bytesdownloading of 393216 bytes finished
Received 16 bytes: flash:bootloader
flashing 'bootloader'
Writing BL1 to sector 1 (16 sectors).. checksum : 0xed75e
writing bootloader.. 49, 1024 
MMC write: dev # 0, block # 49, count 1024 ... 1024 blocks written: OK
completed
partition 'bootloader' flashed

2)对iNand进行重新分区

在烧写完uboot之后一般要重启,此时开发板会运行刚才烧写的uboot,然后在uboot控制台输入“fdisk -c 0”对iNand进行分区。

对iNand重新分区的原因,是之前的uboot对inand的system分区只有100多MB,放不下本次提供的200多MB的根文件系统镜像,如果继续用之前的uboot规划的分区,烧写根文件系统时会提示文件太大放不能进分区。刚刚烧录的uboot.bin已经重新设置了分区信息,烧录并运行它之后,执行“fdisk -c 0”就可以对inand重新分区。

之前的uboot对inand的分区情况如下:

x210 # fdisk -p 0  //查看编号为0的设备(即iNand)的分区情况partion #    size(MB)     block start #    block count    partition_Id 1           258            22374          529518          0x83 2           120           551892          246114          0x83 3           101           798006          208824          0x83 4          3222          1006830         6600330          0x83 
x210 # 

新的uboot对inand进行重新分区之后,inand中的分区情况如下。

x210 # fdisk -p 0partion #    size(MB)     block start #    block count    partition_Id 1           258            22374          529518          0x83 2           258           551892          529518          0x83 3           101          1081410          208824          0x83 4          3084          1290234         6316926          0x83 
x210 #

对比可知,重新分区后inand的分区2变为了258MB。

3)烧录内核镜像文件

重新分区之后,在uboot控制台输入fastboot命令。

然后在windows控制台输入“fastboot flash kernel zImage-qt ”。

windows控制台与uboot控制台显示的内容如下:

C:\Users\34316\Desktop\fastboot>fastboot flash kernel zImage-qt
sending 'kernel' (3566 KB)... OKAY
writing 'kernel'... OKAY
Received 17 bytes: download:0037b800
Starting download of 3651584 bytes
...
downloading of 3651584 bytes finished
Received 12 bytes: flash:kernel
flashing 'kernel'
writing kernel.. 1073, 8192 
MMC write: dev # 0, block # 1073, count 8192 ... 8192 blocks written: OK
completed
partition 'kernel' flashed

4)烧录根文件系统镜像文件

在windows控制台输入“fastboot flash system rootfs_qt4.ext3 ”。

windows控制台与uboot控制台显示的内容如下:

C:\Users\34316\Desktop\fastboot>fastboot flash system rootfs_qt4.ext3
sending 'system' (262144 KB)... OKAY
writing 'system'... OKAY
Received 17 bytes: download:10000000
Starting download of 268435456 bytes
................................................................................
................................................................................
................................................................................
...............
downloading of 268435456 bytes finished
Received 12 bytes: flash:system
flashing 'system'MMC write: dev # 0, block # 551892, count 529518 ... 529518 blocks written: OK
partition 'system' flashed

二、fastboot命令的源码分析

接下来将分析fastboot命令在uboot端的源码,重点在于分析bootloader、kernel、system这三个标签是如何与inand中具体地址关联的。

在uboot(分区信息尚未修改的uboot)控制台输入fastboot时显示下面信息:

x210 # fastboot
[Partition table on MoviNAND]
ptn 0 name='bootloader' start=0x0 len=N/A (use hard-coded info. (cmd: movi))
ptn 1 name='kernel' start=N/A len=N/A (use hard-coded info. (cmd: movi))
ptn 2 name='ramdisk' start=N/A len=0x300000(~3072KB) (use hard-coded info. (cmd: movi))
ptn 3 name='config' start=0xAECC00 len=0x1028DC00(~264759KB) 
ptn 4 name='system' start=0x10D7A800 len=0x782C400(~123057KB) 
ptn 5 name='cache' start=0x185A6C00 len=0x65F7000(~104412KB) 
ptn 6 name='userdata' start=0x1EB9DC00 len=0xC96D1400(~3300165KB) 
Insert a OTG cable into the connector!

在修改分区信息之后的uboot控制台输入fastboot时显示下面信息:

x210 # fastboot
[Partition table on MoviNAND]
ptn 0 name='bootloader' start=0x0 len=N/A (use hard-coded info. (cmd: movi))
ptn 1 name='kernel' start=N/A len=N/A (use hard-coded info. (cmd: movi))
ptn 2 name='ramdisk' start=N/A len=0x300000(~3072KB) (use hard-coded info. (cmd: movi))
ptn 3 name='config' start=0xAECC00 len=0x1028DC00(~264759KB) 
ptn 4 name='system' start=0x10D7A800 len=0x1028DC00(~264759KB) 
ptn 5 name='cache' start=0x21008400 len=0x65F7000(~104412KB) 
ptn 6 name='userdata' start=0x275FF400 len=0xC0C6FC00(~3158463KB)

可见这里有bootloader、kernel、…、userdata等标签,似乎是分区标志,但它们不是真正意义上的分区(因为没有写进主引导扇区中),它们只是用来表征iNand中某段存储空间的字符串,或者说用来表征iNand中某个(以扇区为单位的)偏移地址的字符串(这两种说法意思一样,前者指整段空间,后者指整段空间的开头)。

比如在uboot下使用movi命令(例如movi read kernel xxxxx),或者“fastboot flash kernel 内核镜像文件”时,参数kernel只是一个(表征着某个扇区地址的)字符串。

那么这些标签和与之对应的地址,是在哪里定义的呢?

1、set_partition_table函数

我们知道,uboot执行fastboot命令时,会调用do_fastboot函数。通览do_fastboot函数,其中与分区有关的是set_partition_table函数。该函数定义在/common/cmd_fastboot.c文件中。

删除条件编译等内容,该函数内容如下:

static int set_partition_table()
//删除一些条件编译的代码#elif defined(CFG_FASTBOOT_SDMMCBSP)
{int start, count;unsigned char pid;pcount = 0;#if defined(CONFIG_FUSED)    //没有定义这个宏/* FW BL1 for fused chip */strcpy(ptable[pcount].name, "fwbl1");ptable[pcount].start = 0;ptable[pcount].length = 0;ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;pcount++;
#endif/* Bootloader */strcpy(ptable[pcount].name, "bootloader");ptable[pcount].start = 0;ptable[pcount].length = 0;ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;pcount++;/* Kernel */strcpy(ptable[pcount].name, "kernel");ptable[pcount].start = 0;ptable[pcount].length = 0;ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;pcount++;/* Ramdisk */strcpy(ptable[pcount].name, "ramdisk");ptable[pcount].start = 0;ptable[pcount].length = 0x300000;ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;pcount++;/* Config */get_mmc_part_info("0", 1, &start, &count, &pid);if (pid != 0x83)goto part_type_error;strcpy(ptable[pcount].name, "config");ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE;ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE;ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD;pcount++;/* System */get_mmc_part_info("0", 2, &start, &count, &pid);if (pid != 0x83)goto part_type_error;strcpy(ptable[pcount].name, "system");ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE;ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE;ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD;pcount++;/* Cache */get_mmc_part_info("0", 3, &start, &count, &pid);if (pid != 0x83)goto part_type_error;strcpy(ptable[pcount].name, "cache");ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE;ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE;ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD;pcount++;/* Data */get_mmc_part_info("0", 4, &start, &count, &pid);if (pid != 0x83)goto part_type_error;strcpy(ptable[pcount].name, "userdata");ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE;ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE;ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD;pcount++;#if 1 // Debugfastboot_flash_dump_ptn();
#endif//省略部分代码
}

由此可知,这个函数只设置了config、system、cache、userdata这些标签所对应的空间(起始扇区、扇区数目、标志),没有对bootloader、kernel、ramdisk这些标签进行设置。

如何设置的呢?以config标签为例说明设置过程。

首先,代码“get_mmc_part_info("0", 1, &start, &count, &pid);”。第一个参数0表示存储设备的编号为0,也就是iNand;第二个参数1表示这个存储设备的分区1(下面2,3,4是分区2,3,4);第三第四第五个参数前面的&,表示它们是输出型参数,其中start表示分区1的以扇区为单位的起始地址,count表示分区1有多少个扇区。这个函数返回时,start=22374,count=529518。

然后,将分区1的以扇区为单位的起始地址转换成以字节为单位的起始地址,将分区1的扇区总数转换成以字节为单位的空间大小。这里的CFG_FASTBOOT_SDMMC_BLOCKSIZE值为512,因为一个扇区大小是512字节。

因为22374*512=11455488(10)= AECC00(16),529518*512=1028DC00(16),因此config标签对应的空间信息为:start=AECC00,length=1028DC00。

这与执行fastboot命令时显示的数据是一样的(执行fastboot命令时之所以会显示信息,是因为函数do_fastboot中间接调用了fastboot_flash_dump_ptn函数,该函数用来打印这些信息)。

同理可以得到其他标签对应的空间的信息,这里不赘述。

注意,config标签所对应的空间与分区1是一致的,因为本来就是先调用get_mmc_part_info函数来获取分区1的数据,然后用这些数据来填充(congfig标签所对应的空间的数据结构)ptable[0]。

同理system标签所对应的空间与分区2的空间是一致的。我们知道,system标签所对应的空间是用来烧录根文件系统的,也就是说根文件系统将来存储在system标签所对应的空间,由于这个空间与分区2的空间一致,所以可以说根文件系系统位于分区2,因此uboot给kernel传参时,bootargs里面有一个项目“root=mmcblk0p2 rw”,表示的就是根文件系统在设备0的第2分区。

同理cache、userdata标签所对应的空间与分区3、分区4一致。

因此,fastboot命令体系下的“分区表”如下。

分区号分区名称
ptable[0]bootloader(暂无对应)
ptable[1]kernel(暂无对应)
ptable[2]ramdisk(暂无对应)
ptable[3]config(对应着分区1)
ptable[4]system(对应着分区2)
ptable[5]cache(对应着分区3)
ptable[6]userdata(对应着分区4)

上面写到,set_partition_table函数只是设置了config、system、cache、userdata这些标签对应的空间,没有对bootloader、kernel、ramdisk这些标签进行设置(只是简单地设置为0)。

我们利用fastboot flash来烧录镜像时,常用bootloader,kernel,system这三个标签。其中system标签对应的空间是分区2,那bootLoader、kernel标签对应什么空间呢?

注意到执行fastboot时,关于bootloader、kernel、ramdisk标签,显示的内容中有“(use hard-coded info. (cmd: movi))”,这说明这三个标签可能以硬编码方式写在了movi命令对应的函数中。

对do_movi函数进行分析(见博文do_movi函数的源码分析),可知该命令体系下也有一个“分区表”(没有写入主引导区),叫做raw分区表,分区表里有u-boot、kerne、rfs等分区,这些分区都有实实在在的范围,而不像fastboot命令体系下bootLoader、kernel、ramdisk分区那样没有实实在在的范围(简单地设置为0而已)。

fastboot命令体系下的kernel分区,兴许对应着movi命令体系下的kernel分区,因为两者都是用字符串“kernel”表示。fastboot命令体系下的bootloader分区,与movi命令体系下的u-boot分区,两者的名字不同但意义一样,会不会也是对应关系呢?如果是,执行“fastboot flash bootloader uboo.bin”时,bootloader这个标签是如何转为u-boot的。

另外经过思考,既然使用“movi write u-boot xxxxxx”时,表示将内存地址xxxxx处的内容写进(也就是烧录)到inand的ub-boot分区,使用“fastboot flash bootloader uboo.bin”时表示将uboot的镜像文件写进bootloader分区,两者操作本质一样,那fastboot flash在uboot端应该也采用movi命令。

选择几个执行“fastboot flash bootloader uboo.bin”时在uboot中显示的内容的关键词,定位到位于/common/cmd_fastboot.c文件中的rx_handler函数。

该函数的部分内容如下:

static int rx_handler (const unsigned char *buffer, unsigned int buffer_size)
{//省略部分代码/* flashFlash what was downloaded */if (memcmp(cmdbuf, "flash:", 6) == 0){//省略部分代码struct fastboot_ptentry *ptn;ptn = fastboot_flash_find_ptn(cmdbuf + 6);//省略部分代码/* Normal case */if (write_to_ptn(ptn, (unsigned int)interface.transfer_buffer, download_bytes)){printf("flashing '%s' failed\n", ptn->name);sprintf(response, "FAILfailed to flash partition");}else{printf("partition '%s' flashed\n", ptn->name);sprintf(response, "OKAY");}}
}

其中的write_to_ptn函数内容与分析如下:

/*
该函数功能是将镜像写进fastboot命令体系下的分区。
以执行“fastboot flash bootloader uboot.bin”为例进行说明。
以执行“fastboot flash system rootfs_qt4.ext3”为例进行说明。
*///fastboot命令体系下的某个分区名,储存着待烧录数据的某个内存地址,待烧写的数据长度
static int write_to_ptn(struct fastboot_ptentry *ptn, unsigned int addr, unsigned int size)
{                                         int ret = 1;char device[32], part[32];char start[32], length[32], buffer[32];char *argv[6]  = { NULL, "write", NULL, NULL, NULL, NULL, };/* 此时argv[1]="write"。根据下面的分析,write_to_ptn函数调用do_movi函数或者do_mmcops来完成烧写。填充这个字符指针数组,其实是在构造“movi write u-boot xxxxx”或者“mmc write system …”字符串。*/int argc = 0;if ((ptn->length != 0) && (size > ptn->length))//因为bootloader的ptn->length=0,所以不会执行。{											   //假定要烧写的根文件系统镜像小于system分区,因此不会执行。//可见这里烧录的镜像如果大于该分区,则会报错返回。printf("Error: Image size is larger than partition size!\n");return 1;}printf("flashing '%s'\n", ptn->name);// 打印信息“ flashing 'bootloader'”或者“ flashing 'system' ”。if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD)//表示在烧写system分区{argv[2] = device;//argv[0]=NULL,argv[1]="write"argv[3] = buffer;argv[4] = start;argv[5] = length;sprintf(device, "mmc %d", 1); //argv[2]="mmc 1"sprintf(buffer, "0x%x", addr);//argv[3]="0x内存地址",表示储存着待烧录数据的某个内存地址sprintf(start, "0x%x", (ptn->start / CFG_FASTBOOT_SDMMC_BLOCKSIZE));  //argv[4]="0x分区起始扇区"(system分区起始扇区号)sprintf(length, "0x%x", (ptn->length / CFG_FASTBOOT_SDMMC_BLOCKSIZE));//argv[5]="0x分区扇区总数"(system分区扇区的总数)ret = do_mmcops(NULL, 0, 6, argv);//注意内部是怎么写的/*argv[0]=NULLargv[1]="write"argv[2]="mmc 1"argv[3]="0x内存地址"argv[4]="0x分区起始扇区"argv[5]="0x分区扇区总数"*/}else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD)//表示是在烧写bootloader、kernel{argv[2] = part;//argv[0]=NULL,argv[1]="write"argv[3] = buffer; argc = 4;//argc = 4/* use the partition name that can be understood by a command, movi */if (!strcmp(ptn->name, "bootloader"))//简单理解为,给bootloader换个别名{strncpy(part, "u-boot", 7);//将fastboot的分区“bootloader”转换成movi中的分区“u-boot”,这里argv[2]="u-boot"}else if (!strcmp(ptn->name, "ramdisk"))//没涉及到这个,略过{strncpy(part, "rootfs", 7);argv[4] = length;sprintf(length, "0x%x",	((size + CFG_FASTBOOT_SDMMC_BLOCKSIZE - 1)/CFG_FASTBOOT_SDMMC_BLOCKSIZE ) * CFG_FASTBOOT_SDMMC_BLOCKSIZE);argc++;//argc = 5}/* kernel, fwbl1 */  //这里表示在烧写kernelelse{argv[2] = ptn->name;//因为kernel在fastboot中的分区名和在movi中的分区名一致,所以直接赋值}sprintf(buffer, "0x%x", addr);//argv[3]="0x内存地址"(表示储存着待烧录数据的某个内存地址)ret = do_movi(NULL, 0, argc, argv);/* argc=4,argv[0]=NULLargv[1]="write"argv[2]="u-boot" argv[3]="0x内存地址"argv[4]="0x数据长度"argv[5]=NULL*//* the return value of do_movi is different from usual commands. Hence the followings. */ret = 1 - ret;}return ret;
}

由此可知

(1)bootloader转换成u-boot,是在write_to_ptn函数中完成的。

(2)write_to_ptn函数通过调用do_mmcops(NULL, 0, 6, argv)来完成system区的烧写。

(3)write_to_ptn函数通过调用do_movi(NULL,0,argc,argv)来完成bootloader或kernel区的烧写。在do_movi函数中,调用movi_write_bl1(addr)函数来完成bl1在扇区1~16的烧写,调用run_command(run_cmd, 0)函数来完成bl2在49~xxx扇区的烧写。

而run_command(run_cmd, 0)通过运行命令解析函数,得知要执行mmc命令,而mmc命令又对应着函数do_mmcops,而system分区的烧写也是由这个函数完成的,因此有必要分析do_mmcops函数。

该函数主要实现从MMC中读数据或者写数据到MMC中。

三、fdisk\fastboot\movi三者的分区表关系

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你知道自己执行的是哪个jre吗?

多个JRE 我在做《Java日志工具之java.util.logging.Logger》的DEMO时,修改java.util.logging.Logger的配置文件,怎么修改都不起作用,因此打印了系统属性"java.home",才知道自己使用的是 C:\Program Files\Java\jre7 &am…

无需写try/catch,也能正常处理异常

对于企业应用的开发者来说,异常处理是一件既简单又复杂的事情。说其简单,是因为相关的编程无外乎try/catch/finallythrow而已;说其复杂,是因为我们往往很难按照我们真正需要的策略来处理异常。我一直有这样的想法,理想…

vs2010插件

转载于:https://www.cnblogs.com/tinytiny/p/3608030.html

leetcode1——两数之和

一、提出问题 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按…

如何脱离SDK,使用DW5.5和phonegap以及JQMobile搭建开发环境

也许有些人是学C出身,对于Java几乎不了解。一时心血来潮想学学android开发,于是下载了Eclipse,安装了SDK,有模有样的学习起来。也许是懒惰了,对于java一直总是提不起精神。于是确定使用DreamweaverJquery mobilePhoneg…

leetcode2——两数相加

一、提出问题 给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以…

32为Linux安卓AVD启动报错

2019独角兽企业重金招聘Python工程师标准>>> 当使用android的AVD时提示以下错误:Starting emulator for AVD NexusOne ERROR: 32-bit Linux Android emulator binaries are DEPRECATED, to use them you will have to do at least one of the following:…

填问卷,得《2015中国呼叫中心知识库现状与问题报告》

为了解中国呼叫中心知识库运营现状和存在的主要问题,掌握呼叫中心知识库的总体发展水平,中国知识管理中心(KMCenter)面向全国呼叫中心发起“2015中国呼叫中心知识库现状与问题调研”活动,主要通过问卷调研和典型用户访…

ARM汇编的特点

以下内容源于网络资源的学习与整理,如有侵权请告知删除。 一、LDR/STR架构 ARM采用RISC架构,CPU本身不能直接读取内存,需要先将内存中的内容加载到CPU的通用寄存器中才能被CPU处理。换言之,寄存器是CPU和内存进行数据交换的中介。…

持久代是方法区还是堆中的?

2019独角兽企业重金招聘Python工程师标准>>> 昨天跟一哥们讨论,持久代在方法区,属不属于堆中的? 它的意思是持久代不属于堆,属于方法区,而我则认为持久代属于方法区也属于堆。 结果今天上网一查,还真的是。下面是解释: 持久代”仅…

Web 前端攻防(2014版)-baidu ux前端研发部

http://fex.baidu.com/articles/page2/ Web 前端攻防(2014版) zjcqoo | 20 Jun 2014禁止一切外链资源 外链会产生站外请求,因此可以被利用实施 CSRF 攻击。 目前国内有大量路由器存在 CSRF 漏洞,其中相当部分用户使用默认的管理账…

Silverlight动态设置WCF服务Endpoint

2013-02-02 05:57 by jv9, 1763 阅读, 3 评论, 收藏, 编辑 去年12月收到一位朋友的邮件,咨询Silverlight使用WCF服务,应用部署后一直无法访问的问题,通过几次交流,才发现在他的项目中,全部使用静态URL作为WCF服务的End…

第4季3:Hi3518e的sensor接口引脚复用设置(load3518e文件)

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。 在第2、3季的内容中,在板载系统的配置脚本即/etc/profile文件中,都有如下这句代码: ./load3518e -i -sensor ar0130 -osmem 32 -total 64 在第4季1&#xff1a…

iOS游戏开发 几个有利工具

2019独角兽企业重金招聘Python工程师标准>>> iOS游戏开发 几个有利工具 本文介绍的是iOS游戏开发 几个有利工具,为友们介绍几款开发工具,游戏爱好者记住了!先来看内容。 AD: iOS游戏开发 几个有利工具是本文要介绍的内…

关于editor网页编辑器ueditor.config.js 配置图片上传

最近公司项目在做一个门户网站,其中新闻和简介等部分使用到了ueditor编辑器,但是上级明确指示需要图片上传这个功能,这时却发现图片上传功能不能正常使用,上传时一直报错,网上收了好几个处理办法,都说的不够…

[歪谈]拽一个贵人出来给你当炮架子

[歪谈]拽一个贵人出来给你"当炮架子" 我们在古装神话剧中经常会听到某个“先知”对前来算命的人说:你会在某某时刻遇到你的贵人。而这个贵人会在事业上助你一臂之力。 这里有个问题:贵人到底是什么?我们怎样去寻找我们的贵人。 前几…

第6季1:H264编码原理与基本概念

以下内容源于网络资源的学习与整理,如有侵权请告知删除。 参考博客 (1)H264 编码基本原理_ByteSaid的博客-CSDN博客_h264编码原理 (2)H264 编码简介_mydear_11000的博客-CSDN博客 (3)什么是I帧…

pureMVC简单示例及其原理讲解四(Controller层)

本节将讲述pureMVC示例中的Controller层。 Controller层有以下文件组成: AddUserCommand.asDeleteUserCommand.asModelPrepCommand.asViewPrepCommand.asStartupCommand.asAddUserCommand 。顾名思义,它是添加用户命令。让我们首先看看代码。 Addusercom…

ActiveMQ学习笔记(2)——JMS消息模型

2019独角兽企业重金招聘Python工程师标准>>> 1.1 JMS模型简介 JMS支持两种消息通信模型: 点对点模型(Point to Point,P2P)发布者/订阅者模型(publish/subscribe, pub/sub)P2P模型中,Sender把一…

C# 图片盖章功能实现,支持拖拽-旋转-放缩-保存

实现图片盖章功能,在图片上点击,增加“图章”小图片,可以拖拽“图章”到任意位置,也可以点击图章右下角园框,令图片跟着鼠标旋转和放缩。 操作方法:1.点击增加“图章”2.选中移动图标3.点中右下角放缩旋转图…