数据专栏

智能大数据搬运工,你想要的我们都有

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

「深度学习福利」大神带你进阶工程师,立即查看>>>
准备工作:
需要win10系统的电脑
需要Microsoft 账户,可以自己去注册。
并且需要注册 Windows 预览体验计划才能下载该 Insider Preview。

然后获取镜像文件。

选择版本信息以及选择设备,确认后就可以跳转到下载页面进行下载。

找到刚才下载的ISO文件,双击可以出现安装信息,直接安装就可以完成。

接下来还需要安装Dashboard,通过这个下载程序到SD卡或者TF卡中。

设置新的设备

通过browser来查找之前安装文件中的.ffu文件。一般的路径应该在下面的路径中查找:
"C:\Program Files (x86)\Microsoft IoT\FFU\ DeviceType " and select Flash.ffu.
插入你的TF卡,系统会自己找到这个设备,显示在页面上面。程序烧写过程中。。。只能等待了。

终于烧写完成的啊!不容易啊。

完成以后将TF卡插到树莓派中,插上网线,上电后等待一会,在你的win10电脑中可以看到它已经连接到网络了,可以通过电脑查看在线情况。

双击可以查看板子的详细信息。

我们再来用显示器来看看效果吧!

这是设置语言的对话框,手抖了下,照片不是很清楚啊,见谅!

上面是关于蓝牙的设置,可以看到这里是不能设置的,主要是因为我们现在能够使用的镜像不是正式版的,这个镜像应该是在2代的基础上改的,还没有添加蓝牙这个功能。期待后面会更新吧。
wifi功能很正常啊,可以搜索到无线信号:


可以看到系统里面有4个之前有人做的实验了,通过这个系统自己应该可以根据这些提示来完成。有时间可以体验一下。下面是其中一个例子的展示,就是控制I/O口的LED状态。
我们可以看到这些例子的实现都是基于VS的,在这个软件的基础上可以开发许多的应用。
自此这个系统的安装和体验完成了。我们可以发现和PC的系统,最大的区别在于GUI的,系统精简。运行比较流畅,1A的 电源 适配器能跑,但是可以看得出来已经不够用了。在IoT里面应该会有很强的应用。
硬件开发
2016-09-30 14:35:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
玩板子由于需要频繁进行文件烧写、传输和下载,所以经常会用到标题中提到的几种服务。刚接触嵌入式时,老是对这几种服务分不清,对几种服务的用法及功能也比较模糊,现在特意查找资料,记录下来。
FTP:
FTP(File Transfer Protocol, 文件传输协议), 是 TCP/IP 协议组种的协议之一。FTP 协议包括两部分,其一为 FTP 服务器,其二为 FTP 客户端。FTP 服务器用来存储文件,用户可以通过使用 FTP 客户通过 FTP 协议访问位于 FTP 服务器上的资源。在开发网站的时候,通常利用 FTP 协议把网页或程序传到 web 服务器上。此外,由于 FTP 传输效率非常高,在网络传输大的文件时,一般也采用该协议。
默认情况下,FTP 协议使用 TCP 端口中的20和21这两个端口。20用于传输数据,21用于传输控制信息。但是否使用20端口作为传输数据的端口与 FTP 使用的传输模式有关。如果采用主动模式,那么数据传输端口就是20;若是被动模式,则需服务器与客户端协商决定使用哪个端口。
FTP 地址格式如下:
ftp://用户名:密码@FTP服务器IP或域名:FTP命名端口/路径/路径
FTP 安装:
sudo apt-get install vsftpd
FTP 配置:
修改 vsftpd 的配置文件 /etc/vsftpd.conf, 将下面两行的 '#' 号去掉
#local_enable = yes 允许本地用户登录
#write_enable = yes 允许上传文件

SSH:
SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为 远程登录 会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。SSH最初是UNIX系统上的一个程序,后来又迅速扩展到其他操作平台。SSH在正确使用时可弥补网络中的漏洞。SSH客户端适用于多种平台。几乎所有UNIX平台—包括 HP-UX 、 Linux 、 AIX 、 Solaris 、 Digital UNIX 、 Irix ,以及其他平台,都可运行SSH。
SSH 服务安装:
sudo apt-get install openssh-server
配置文件为 /etc/ssh/sshd_config
重启ssh 服务: 直接执行 /etc/rc.d/init.d/ssh restart 或者 sevice ssh restart restart 包括了stop,start。

NFS 服务:
NFS (Network File System, 网络文件系统),是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过 TCP/IP 网络共享资源。在 NFS 的应用中, 本地 NFS 的客户端应用可以透明地读写位于远端 NFS 服务器上的文件,就像访问本地文件一样。
NFS 安装:
sudo apt-get install nfs-kernel-server portmap
NFS 配置:
配置文件 /etc/exports, 在里面增加一些内容,可以通过网络文件系统访问 /work/nfs_root 目录
/work/nfs_root *(rw, sync, no_root_squash)
rw: 客户端对此目录有读写权限
sync:资料同步写入内存和硬盘
no_root_squash:root 用户具有对根目录的完全管理访问权限
之后重启 nfs:
sudo /etc/init.d/nfs-kernel-server restart

TFTP:
TFTP (Trivial File Transfer Protocol, 简单文件传输协议) 是 TCP/IP 协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销小的文件传输服务。端口号为69.TFTP是一个传输文件的简单协议,它基于UDP协议而实现,但是我们也不能确定有些TFTP协议是基于其它 传输协议 完成的。此协议设计的时候是进行小 文件传输 的。因此它不具备通常的FTP的许多功能,它只能从 文件服务器 上获得或写入文件,不能列出目录,不进行认证,它传输8位数据。传输中有三种模式:netascii,这是8位的ASCII码形式,另一种是octet,这是8位源 数据类型 ;最后一种mail已经不再支持,它将返回的数据直接返回给用户而不是保存为文件。
安装 TFTP:
sudo apt-get install openbsd-inetd tftpd tftp
配置 TFTP:
修改配置文件 /etc/inetd.conf 里面有一行:
tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /srv/tftp
把 "nobody" "/srv/tftp" 改为 "root", "/work/nfs_root", 表示 tftp 目录。
硬件开发
2016-09-28 22:54:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
随机复制下面的几四个注册码 粘贴到sublime text 3(Build 3103)注册框 就可以了!
-------------------------------------------------------------------------------
第一个--first licence key :
========================================
—– BEGIN LICENSE —–
Michael Barnes
Single User License
EA7E-821385
8A353C41 872A0D5C DF9B2950 AFF6F667
C458EA6D 8EA3C286 98D1D650 131A97AB
AA919AEC EF20E143 B361B1E7 4C8B7F04
B085E65E 2F5F5360 8489D422 FB8FC1AA
93F6323C FD7F7544 3F39C318 D95E6480
FCCC7561 8A4A1741 68FA4223 ADCEDE07
200C25BE DBBC4855 C4CFB774 C5EC138C
0FEC1CEF D9DCECEC D3A5DAD1 01316C36
—— END LICENSE ——
========================================
第二个--second licence key :
========================================
—– BEGIN LICENSE —–
Nicolas Hennion
Single User License
EA7E-866075
8A01AA83 1D668D24 4484AEBC 3B04512C
827B0DE5 69E9B07A A39ACCC0 F95F5410
729D5639 4C37CECB B2522FB3 8D37FDC1
72899363 BBA441AC A5F47F08 6CD3B3FE
CEFB3783 B2E1BA96 71AAF7B4 AFB61B1D
0CC513E7 52FF2333 9F726D2C CDE53B4A
810C0D4F E1F419A3 CDA0832B 8440565A
35BF00F6 4CA9F869 ED10E245 469C233E
—— END LICENSE ——
========================================
第三个--third licence key :
========================================
—– BEGIN LICENSE —–
Anthony Sansone
Single User License
EA7E-878563
28B9A648 42B99D8A F2E3E9E0 16DE076E
E218B3DC F3606379 C33C1526 E8B58964
B2CB3F63 BDF901BE D31424D2 082891B5
F7058694 55FA46D8 EFC11878 0868F093
B17CAFE7 63A78881 86B78E38 0F146238
BAE22DBB D4EC71A1 0EC2E701 C7F9C648
5CF29CA3 1CB14285 19A46991 E9A98676
14FD4777 2D8A0AB6 A444EE0D CA009B54
—— END LICENSE ——
========================================
第四个--fourth licence key :
========================================
—– BEGIN LICENSE —–
Alexey Plutalov
Single User License
EA7E-860776
3DC19CC1 134CDF23 504DC871 2DE5CE55
585DC8A6 253BB0D9 637C87A2 D8D0BA85
AAE574AD BA7D6DA9 2B9773F2 324C5DEF
17830A4E FBCF9D1D 182406E9 F883EA87
E585BBA1 2538C270 E2E857C2 194283CA
7234FF9E D0392F93 1D16E021 F1914917
63909E12 203C0169 3F08FFC8 86D06EA8
73DDAEF0 AC559F30 A6A67947 B60104C6
—— END LICENSE ——
========================================
硬件开发
2016-09-28 09:16:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
前言:刚开始采用网上介绍的在线安装方式,Eclipse Plugin: http://activiti.org/designer/update/
不过不知是网络慢还是其它原因,始终安装不上去。因此只好采用了links依赖的插件安装方式。
一、 首先将插件下载到本地:
eclipse的activiti-designer各个插件版本可到此处下载: http://www.activiti.org/designer/archived/
注:我这边可能网络环境不稳定,先是无线连网下载,结果连下载了几次,都提示下载文件不能解压,显示文件损坏,还以为是网站上的文件是损坏的。最后无意插入了一根网线,速度好了一些,再尝试下载,就显示好了,此是小插曲,提示网络不好的同学,可能下载下来也会遇到我这样的问题。
接下来就是正式安装了
二、links依赖安装(推荐)
一般来说,eclipse插件采用在线安装后,都是安装在plugins目录下。这样一来,当安装了许多插件之后,eclipse变的很大,最主要的是不便于更新和治理众多插件。用links方式安装eclipse插件,可以解决这个问题。并且link方式便于管理,可以很轻易的根据配置,来安装或卸载插件。
1、将zip插件包解压到eclilpse里的一个自定义目录里,如下:
注1:eclipse-designer是我的eclipse目录,在里面新建my-plugins目录,最后将zip解压的文件放入到eclipse目录里面,听说上级目录必须是eclipse,这个倒没深究,反正先按着规则用吧。
注2:开始我解压出来artifacts和content都是压缩包,在此则将他们也解压出来。
2、然后再在eclipse目录里新建一个links文件夹,里面新建一个以.link后缀的文件,如下:
3、flowcharts-designer.link文件里面的配置 如下:
路径设为相对路径:path=../my-plugins/flowcharts-designer,也可设为绝对路径。
注:插件若放在eclipse文件夹外面,则依赖引入貌似不起效果,此为一问题!
4、重启eclipse后,因为有新的插件,所以会出现eclipse的初始界面,也差不多预示着插件安装成功了:
5、接着打开Window——Preferences,若看到Activiti选项,则表明Eclipse Activiti Designer插件安装成功 如下:
硬件开发
2016-09-27 16:38:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
一、需要软件
1、小米手机驱动程序: 小米驱动.rar (若打不开,请点击后面地址) 或者 小米驱动.rar。
2、小米线刷工具或刷机软件: MiFlash20111223.zip (若打不开,请点击后面地址)或者 MiFlash20111223.zip 。
3、 小米刷机包 :具体见官方下载,注意线刷包的文件名上有个FASTBOOT字样。
二、名词解释
1、卡刷:一般来说卡刷可以简单的理解为在内存卡中刷机,就是进入Recovery中刷入系统。
2、线刷:线刷可以简单的理解为用USB线刷机,一定要注意的是文件路径和驱动。线刷包的文件名上有个FASTBOOT字样。
3、OTA:OTA就是在线刷机,只要在系统中在线升级就可以成功刷机。
4、三清:三清数据时进入Recovery -> 清除数据 -> 清除缓存,清空用户数据,清空所有数据,记的清除前先用MIUI备份(MIUI备份刷机之前都要用到!刷机不会删除内存卡上的文件!)
三、具体步骤(由于刷机时没有截图,于是就从网上找了些图片,不影响小米线刷粉们的阅读使用)
注意:由于目前V4.0的还是不很稳定,故本文介绍的均为V2.3.5的步骤。
1、备份。(系统工具-备份-新建备份)备份重要的数据。
2、下载上述需要的软件及刷机包。
3、解压缩并安装小米驱动。
4、手机进入Recovery (方法:关机,然后 音量上+电源)。
5、手机三清(方法:Recovery -> 清除数据 -> 清除缓存,清空用户数据,清空所有数据)。
6、手机关机。
7、手机进入FASTBOOT(方法:米键+音量下+电源《米2,音量下+电源》)。
8、解压刷机包并复制文件夹所在路径。
9、用USB线连接电脑。
10、解压MiFlash并双击MiFlash.exe,将上面复制的路径粘贴到下图方框内,点击Refresh,刷机程序会自动识别手机,点击Flash开始刷机。
11、刷完之后会提示操作成功,完成正常时间约在300-500s之间,成功后手机会自动重启。
12、重复上述第4、5和6步进行手机三清。
13、手机重启并恢复备份的数据(系统工具-备份-选定备份项目-开始恢复)。
硬件开发
2016-09-17 17:45:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
首先本地先安装一个服务,去下载zip就好啦·~就不多说啦~~
从安装好的mysql目录下复制一份,放到边上就好,如下图
MySQL Server 5.0是我安装好的 服务,下边是我自己复制过来的。
修改5.0.1目录下的my.ini文件:
主要是修改端口,根目录地址,数据目录地址。
然后进入5.0.1\bin 目录,输入:mysqld-nt install mysqlsalve;随后提示你服务创建成功。搞定后,要去注册表更换一下文件,修改服务的可执行路径。
运行regedit 打开 windows 注册表编辑器在下列项目中找到
HKEY_LOCAL_MACHINE\SYSTEM\CURRENTCONTROLSET\SERVICES\对应的服务
修改对应的ImagePath为"C:\Program Files (x86)\MySQL\MySQL Server 5.0.1\bin\mysqld" --defaults-file="C:\Program Files (x86)\MySQL\MySQL Server 5.0.1\my.ini" mysqlsalve
mysql -uroot -hlocalhost -p 密码与你安装的mysql的密码是一样的~~好啦,搞定了~~

之前的是5.0的,太久了,所以打算重新装一些,就去mysqll上边下载,重装了一下~~结果·~很恶心,我只能说~
它不支持-default-file的参数,所以要删除,然后data是自动生成的,使用
mysqld --initialize-insecure (不设置root密码,建议使用)
然后在之行install命令
net start mysql
Mysql –hlocalhost –uroot –p
root这个账号是没有密码的~
硬件开发
2016-09-13 00:46:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
比派科技(banana pi)参加德国 FrOSCon 2016开源盛会
Free Software and Open Source - these are the topics of FrOSCon 2016 Germany.
Bananian开源社区团队与Banana pi 联合参加德国 FrOSCon 2016 开源大会(2016-8-20至2016-8-21)。参展的全系列banana pi产品引起了开源社区的极大关注。
Banana Pi 香蕉派展台:
Banana pi全系列产品,开源的力量无限大,又有两本关于banana pi的德语书籍面世,亚马逊上有售哟,可惜小编看不懂德文。
Banana pi 的开源社区支持:bananian linux社区在banana pi上做了大量开发工作(http://www.bananian.org).
再来一张,有些是新品第一次参展哟。banana pi家族快速发展中.
嗯,bananian linux 的美女。感谢工作人员的勤劳工作。希望更多的人加入banana pi开源社区。
硬件开发
2016-09-07 09:35:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
Using C standard library time and clock functions
硬件开发
2016-09-06 08:59:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
比派科技(banana pi)参加2016香港贸发局香港秋季电子产品展
广东比派科技(banana pi )将于2016年10月 13 号至10月16号参加香港贸发局香港秋季电子产品展, 欢迎各位前来参观指导
展会名称:香港贸发局香港秋季电子产品展2016
时间: 2016年10月13号--10月16号
展台编号:3C-A38
地址: 香港湾仔博览道1号香港会议展览中心

我们在相同的地方,欢迎新老朋友的到来
硬件开发
2016-09-02 17:00:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
PYB Nano v1.1开发板文档
原理图: sch.zip (88.81 KB, 下载次数: 0) 元件表: bom.zip (8.65 KB, 下载次数: 0) 固件: PYB Nano v1.1 开发板固件

3D图:
硬件开发
2016-10-18 22:01:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
昨天MicroPython升级到了1.8.5,这次升级主要在于加入了Zephyr的移植。
完整的更新记录请见 MicroPython官网 。
我们将逐步更新各种开发板的固件,请大家关注。
http://www.micropython.org.cn/forum.php?mod=viewthread&tid=285
硬件开发
2016-10-18 13:04:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
1)ubuntu 切换root用户:
sudo su 进入root用户
"Ctrl+Alt+F1":进入root命令行界面;
"Ctrl+Alt+F7":返回图形用户界面;
2)查看ubuntu下串口的命令:
你也可以使用命令:“ ls -l /dev/ttyUSB* ”来查看相关的信息,如下图

至此,我们已经顺利的将串口连接到Ubuntu系统上了,也查看到自己开发板连接的是USB转串口设备/dev/ttyUSB0,如果是普通的串口设备会是/dev/ttyS*.
3)编译生成单个安装包命令:
make package/hello/install
4)pthread编译方法
由于是Linux新手,所以现在才开始接触线程编程,照着GUN/Linux编程指南中的一个例子输入编译,结果出现如下错误:
undefined reference to 'pthread_create'
undefined reference to 'pthread_join'
问题原因:
pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,所以在使用pthread_create()创建线程,以及调用 pthread_atfork()函数建立fork处理程序时,需要链接该库。
问题解决:
在编译中要加 -lpthread参数
gcc thread.c -o thread -lpthread
5) 改变文件或文件夹的所有者
chown pc:pc globalfifo.c改变文件globalfifo.c为pc的拥有者
6)压缩与解压缩到指定目录
用tar命令解压到指定目录
tar zxvf /bbs.tar.zip -C /zzz/bbs(权限不够使用:sudo)
把根目录下的bbs.tar.zip解压到/zzz/bbs下,前提要保证存在/zzz/bbs这个目录
这个和cp命令有点不同,cp命令如果不存在这个目录就会自动创建这个目录!
用tar命令打包
例:将当前目录下的zzz文件打包到根目录下并命名为zzz.tar.gz
#tar zcvf /zzz.tar.gz ./zzz
硬件开发
2016-10-17 10:17:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
1、存储过程的简介:
我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。
一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。
2、存储过程的有点:
(1).存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
(2).存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。
(3).存储过程能实现较快的执行速度。如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。
(4).存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。
(5).存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。
3、关于mysql的存储过程:
存储过程是数据库存储的一个重要的功能,但是MySQL在5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣。好在MySQL 5.0终于开始已经支持存储过程,这样即可以大大提高数据库的处理速度,同时也可以提高数据库编程的灵活性。
同时,要在mysql5.1以上版本创建子程序,必须具有CREATE ROUTINE权限,并且ALTER ROUTINE和EXECUTE权限被自动授予它的创建者;
4、存储过程的创建:
(1)语法:
CREATE PROCEDURE sp_name ([ proc_parameter ]) [ characteristics..] routine_body
proc_parameter指定存储过程的参数列表,列表形式如下:[IN|OUT|INOUT] param_name type
其中in表示输入参数,out表示输出参数,inout表示既可以输入也可以输出;param_name表示参数名称;type表示参数的类型该类型可以是MYSQL数据库中的任意类型有以下取值:
characteristic:
LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'
routine_body:
Valid SQL procedure statement or statements
LANGUAGE SQL :说明routine_body部分是由SQL语句组成的,当前系统支持的语言为SQL,SQL是LANGUAGE特性的唯一值
[NOT] DETERMINISTIC :指明存储过程执行的结果是否正确。DETERMINISTIC 表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出。[NOT] DETERMINISTIC 表示结果是不确定的,相同的输入可能得到不同的输出。如果没有指定任意一个值,默认为[NOT] DETERMINISTIC
CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA :指明子程序使用SQL语句的限制。
CONTAINS SQL表明子程序包含SQL语句,但是不包含读写数据的语句;
NO SQL表明子程序不包含SQL语句;
READS SQL DATA:说明子程序包含读数据的语句;
MODIFIES SQL DATA表明子程序包含写数据的语句。
默认情况下,系统会指定为CONTAINS SQL
SQL SECURITY { DEFINER | INVOKER } :指明谁有权限来执行。DEFINER 表示只有定义者才能执行
INVOKER 表示拥有权限的调用者可以执行。默认情况下,系统指定为DEFINER
COMMENT 'string' :注释信息,可以用来描述存储过程或函数
routine_body是SQL代码的内容,可以用BEGIN...END来表示SQL代码的开始和结束
(2) 格式
MySQL存储过程创建的格式:CREATE PROCEDURE 过程名 ([过程参数[,...]])
[特性 ...] 过程体
EG:
DELIMITER //
DROP PROCEDURE IF EXISTS simpleproc;
CREATE PROCEDURE simpleproc (OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t_user;
END //
DELIMITER ;
我这是在使用Navicat for MySQL 上敲的,就不打算进入mysql客户端去敲了,个人觉得这个更方便快捷一点;如果熟悉linux的童鞋估计就不这么认为啦;
好了,废话不多说,先解释一下:(1)DELIMITER这个东西的作用就是告诉mysql,我的存储过程的结束符号是//,所以在你的存储过程中使用;不会被认为是结束符号; 注:当使用delimiter命令时,你应该避免使用反斜杠(‘\’)字符,因为那是MySQL的 转义字符 (2)drop procedure if exists的意思跟我们建表时的语句是一样的,如果存在这个存储过程则删除;(3)create procedure simpleproc (out param1 int) 的意思也很明确,就是创建这个过程,而且带有一个输出参数, 注:在function中可以有return 语句,但是procedure是没有的,但是也可以做到将结果传回去,如上; (4) begin .... end 这中间包裹着的就是procedure的主程序,也就是主体部分;简而言之,把你要放在一起工作的sql都丢在这里就好;(5)DELIMITER;这个语句作为结束语句。目的是告诉mysql我现在不要使用//作为结束字符了,要换回;了; 注:这个不止可是//,还可以是其他符号;
5、变量
DECLARE语句被用来把不同项目局域到一个 子程序:局部变量,条件和 处理程序 及光标; DECLARE仅被用在BEGIN ... END复合语句里,并且必须在复合语句的开头,在任何其它语句之前 。光标必须在声明处理程序之前被声明,并且变量和条件必须在声明光标或处理程序之前被声明。
declare 声明局部变量:DECLARE var_name[,...] type [DEFAULT value];这个语句被用来声明局部变量。要给变量提供一个默认值,请包含一个DEFAULT子句。值可以被指定为一个表达式,不需要为一个常数。如果没有DEFAULT子句,初始值为NULL。
set 变量:SET var_name = expr [, var_name = expr] ...; 在存储程序中的SET语句是一般SET语句的扩展版本。被参考变量可能是子程序内声明的变量,或者是全局服务器变量。在存储程序中的SET语句作为预先存在的SET语法的一部分来实现。这允许SET a=x, b=y, ...这样的扩展语法。其中不同的变量类型(局域 声明变量及全局和集体变量)可以被混合起来。这也允许把局部变量和一些只对系统变量有意义的选项合并起来。在那种情况下,此选项被识别,但是被忽略了。
6、定义处理程序
有时候程序是会出错的,但是你希望你的程序在出错的情况下继续执行,declare就可以帮助我们解决这样的问题;具体定义如下: 特定条件需要特定处理。这些条件可以联系到错误,以及子程序中的一般流程控制 。定义条件是事先定义程序执行过程中遇到的问题,处理程序定义了在遇到这些问题时候应当采取的处理方式,并且保证存储过程或函数在遇到警告或错误时能继续执行。这样可以增强存储程序处理问题的能力,避免程序异常停止运行
1、定义条件
DECLARE condition_name CONDITION FOR[condition_type]
[condition_type]:
SQLSTATE[VALUE] sqlstate_value |mysql_error_code
condition_name:表示条件名称
condition_type:表示条件的类型
sqlstate_value和mysql_error_code都可以表示mysql错误
sqlstate_value为长度5的字符串错误代码
mysql_error_code为数值类型错误代码,例如:ERROR1142(42000)中,sqlstate_value的值是42000,
mysql_error_code的值是1142 //方法一:使用sqlstate_value DECLARE command_not_allowed CONDITION FOR SQLSTATE '42000' //方法二:使用mysql_error_code DECLARE command_not_allowed CONDITION FOR SQLSTATE 1148

这个语句指定需要特殊处理条件。他将一个名字和指定的错误条件关联起来。
这个名字随后被用在定义处理程序的DECLARE HANDLER语句中

2、定义处理程序
DECLARE handler_type HANDLER FOR condition_value [,...] sp_statement
handler_type :
|CONTINUE:对一个CONTINUE处理程序,当前子程序的执行在执行 处理程序语句之后继续。
| EXIT :对于EXIT处理程序,当 前BEGIN...END复合语句的执行被终止。
| UNDO :UNDO 处理程序类型语句还不被支持。 ·
condition_value :
SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING:SQLWARNING是对所有以01开头的SQLSTATE代码的速记
| NOT FOUND:NOT FOUND是对所有以02开头的SQLSTATE代码的速记
| SQLEXCEPTION:SQLEXCEPTION是对所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE代码的速记
| mysql_error_code
这个语句指定每个可以处理一个或多个条件的处理程序。如果产生一个或多个条件,指定的语句被执行。
//方法一:捕获sqlstate_value DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @info='CAN NOT FIND'; //方法二:捕获mysql_error_code DECLARE CONTINUE HANDLER FOR 1148SET @info='CAN NOT FIND'; //方法三:先定义条件,然后调用 DECLARE can_not_find CONDITION FOR 1146 ; DECLARE CONTINUE HANDLER FOR can_not_find SET set @info='CAN NOT FIND'; //方法四:使用SQLWARNING DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR'; //方法五:使用NOT FOUND DECLARE EXIT HANDLER FOR NOT FOUND SET @info='CAN NOT FIND'; //方法六:使用SQLEXCEPTION DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR'; eg: delimiter // DROP PROCEDURE IF EXISTS sp2; CREATE PROCEDURE sp2() BEGIN DECLARE CONTINUE HANDLER for SQLSTATE '23000' set @info = 23000; SET @info = 1; INSERT INTO test.t_user VALUES (1,'test','test','test'); SET @info = 2; INSERT INTO test.t_user VALUES (1,'test','test','test'); SET @info = 3; END // delimiter ; -- 执行以下sp2 call sp2(); -- 查询以下@info SELECT @info; --结果分析:如果程序没有出错,按照执行目的,结果@info = 3; 如果被捕获了 '23000' 则结果是@23000; 使用continue作为执行handler_type的话,捕获异常就继续执行;所以结果为3; 使用exit作为执行handler_type的话,捕获异常后直接结束,所以结果为23000;
7、光标
简单光标在存储程序和函数内被支持。语法如同在嵌入的SQL中。光标当前是不敏感的,只读的及不滚动的。 不敏感意为服务器可以活不可以复制它的结果表。 光标必须在声明处理程序之前被声明,并且变量和条件必须在声明光标或处理程序之前被声明。

1、声明光标
DECLARE cursor_name CURSOR FOR select_statement
这个语句声明一个光标。也可以在子程序中定义多个光标,但是一个块中的每一个光标必须有唯一的名字。 SELECT语句不能有INTO子句。
2、打开光标
OPEN cursor_name 这个语句打开先前声明的光标。
3、使用光标 FETCH
FETCH cursor_name INTO var_name [, var_name ] ... 这个语句用指定的打开光标读取下一行(如果有下一行的话),并且前进光标指针
4、关闭光标
CLOSE cursor_name 这个语句关闭先前打开的光标。 如果未被明确地关闭,光标在它被声明的复合语句的末尾被关闭。
2、流程控制构造
1.IF语句
IF语句用来进行条件判断。根据是否满足条件,将执行不同的语句。其语法的基本形式如下: IF search_condition THEN statement_list [ELSEIF search_condition THEN statement_list] ... [ELSE statement_list] END IF
其中,search_condition参数表示条件判断语句;statement_list参数表示不同条件的执行语句。
注意:MYSQL还有一个IF()函数,他不同于这里描述的IF语句
下面是一个IF语句的示例。代码如下: delimiter // DROP PROCEDURE IF EXISTS sp3; CREATE PROCEDURE sp3() BEGIN DECLARE age int DEFAULT 19; set @age1 = 0; SET @age2 = 0; set @age3 = 0; IF age>20 THEN SET @age1=age; ELSEIF age=20 THEN SET @age2=age; ELSE SET @age3=-1; END IF; END // delimiter ; call sp3();
该示例根据age与20的大小关系来执行不同的SET语句。
如果age值大于20,那么将count1的值加1;如果age值等于20,那么将count2的值加1;
其他情况将count3的值加1。IF语句都需要使用END IF来结束。
2.CASE语句
CASE语句也用来进行条件判断,其可以实现比IF语句更复杂的条件判断。CASE语句的基本形式如下: CASE case_value WHEN when_value THEN statement_list [WHEN when_value THEN statement_list] ... [ELSE statement_list] END CASE
其中,case_value参数表示条件判断的变量;
when_value参数表示变量的取值;
statement_list参数表示不同when_value值的执行语句。
CASE语句还有另一种形式。该形式的语法如下: CASE WHEN search_condition THEN statement_list [WHEN search_condition THEN statement_list] ... [ELSE statement_list] END CASE
其中,search_condition参数表示条件判断语句;
statement_list参数表示不同条件的执行语句。
下面是一个CASE语句的示例。代码如下: delimiter // DROP PROCEDURE IF EXISTS sp4; CREATE PROCEDURE sp4() BEGIN DECLARE age int DEFAULT 19; set @age1 = 0; CASE age WHEN age > 20 THEN SET @age1 = age; WHEN age = 20 THEN SET @age1 = age-1; ELSE SET @age1 = -1; END CASE; END // delimiter ; call sp4(); select @age1;
注意:这里的CASE语句和“控制流程函数”里描述的SQL CASE表达式的CASE语句有轻微不同。这里的CASE语句不能有ELSE NULL子句
并且用END CASE替代END来终止!!

3.LOOP语句
LOOP语句可以使某些特定的语句重复执行,实现一个简单的循环。
但是LOOP语句本身没有停止循环的语句,必须是遇到LEAVE语句等才能停止循环。
LOOP语句的语法的基本形式如下: [begin_label:] LOOP statement_list END LOOP [end_label]
其中,begin_label参数和end_label参数分别表示循环开始和结束的标志,这两个标志必须相同,而且都可以省略;(例子与leave结合一起写)
4.LEAVE语句
LEAVE语句主要用于跳出循环控制。其语法形式如下: LEAVE label
其中,label参数表示循环的标志。

下面是一个LEAVE语句的示例。代码如下: delimiter // DROP PROCEDURE IF EXISTS sp5; CREATE PROCEDURE sp5() BEGIN set @age = 0; add_age:LOOP SET @age = @age + 1; if @age>1000 THEN LEAVE add_age; end IF; END LOOP add_age; END // delimiter ; -- 调用 call sp5(); -- 查看结果 select @age;
该示例循环执行count加1的操作。当count的值等于100时,则LEAVE语句跳出循环。

5.ITERATE语句
ITERATE语句也是用来跳出循环的语句。但是,ITERATE语句是跳出本次循环,然后直接进入下一次循环。
ITERATE语句只可以出现在LOOP、REPEAT、WHILE语句内。
ITERATE语句的基本语法形式如下: ITERATE label
其中,label参数表示循环的标志。
下面是一个ITERATE语句的示例。代码如下: delimiter // DROP PROCEDURE IF EXISTS sp6; CREATE PROCEDURE sp6() BEGIN DECLARE age int DEFAULT 0; DECLARE EXIT HANDLER FOR SQLSTATE '23000' SET age = 23000; add_fun:LOOP SET age = age + 1; IF age > 10 THEN INSERT into t_user value(1, 'lennon', 'lennon', 'lennon'); ELSEIF age > 5 && age < 10 THEN ITERATE add_fun; ELSE select age; END IF; END LOOP add_fun; END // delimiter ; call sp6();
说明:LEAVE语句和ITERATE语句都用来跳出循环语句,但两者的功能是不一样的。
LEAVE语句是跳出整个循环,然后执行循环后面的程序。而ITERATE语句是跳出本次循环,然后进入下一次循环。
使用这两个语句时一定要区分清楚。

6.REPEAT语句
REPEAT语句是有条件控制的循环语句。当满足特定条件时,就会跳出循环语句。REPEAT语句的基本语法形式如下: [begin_label:] REPEAT statement_list UNTIL search_condition END REPEAT [end_label]
其中,statement_list参数表示循环的执行语句;search_condition参数表示结束循环的条件,满足该条件时循环结束。
下面是一个REPEAT语句的示例。代码如下: delimiter // DROP PROCEDURE IF EXISTS sp7; CREATE PROCEDURE sp7() BEGIN set @age = 0; add_count:REPEAT set @age = @age + 1 ; UNTIL @age>100 END REPEAT add_count; END // delimiter ; call sp7(); select @age;
该示例循环执行count加1的操作,count值为100时结束循环。
REPEAT循环都用END REPEAT结束。

7.WHILE语句
WHILE语句也是有条件控制的循环语句。但WHILE语句和REPEAT语句是不一样的。
WHILE语句是当满足条件时,执行循环内的语句。
WHILE语句的基本语法形式如下: [begin_label:] WHILE search_condition DO statement_list END WHILE [end_label]
其中,search_condition参数表示循环执行的条件,满足该条件时循环执行;
statement_list参数表示循环的执行语句。
下面是一个ITERATE语句的示例。代码如下: delimiter // DROP PROCEDURE IF EXISTS sp8; CREATE PROCEDURE sp8() BEGIN set @age = 0; WHILE @age < 100 DO set @age = @age + 1 ; END WHILE; END // delimiter ; call sp8(); select @age;
该示例循环执行count加1的操作,count值小于100时执行循环。
如果count值等于100了,则跳出循环。WHILE循环需要使用END WHILE来结束。
8、查看存储过程 SHOW { PROCEDURE | FUNCTION } STATUS [ LIKE ' pattern ' ] ; SHOW CREATE { PROCEDURE | FUNCTION } sp_name ; SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME=' sp_name ' ;
eg: show PROCEDURE STATUS like 'sp6'; show CREATE PROCEDURE sp6; SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME='sp6' ;
总结:
终于是整理完一部分了,比较粗糙,但是我相信看完之后会有不小的收获;有一部分是摘抄网络的,有些是摘抄官方手册的,主要目的在于整理自己工作之余的笔记;鄙人菜鸟一枚,如果写的不好,请指出就好,别咬我;这些都是比较基础的整理,但也需要做一个系统的整理学习才能将sql掌握的更好,才能对mysql掌握的更好吧;
流程大致为: 创建->定义变量(光标)->处理程序(有点类似try--catch)->流程控制;



硬件开发
2016-10-16 11:56:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
PYB Nano是目前最小的MicroPython开发板,它只有Nucleo32和Arduino Nano大小,却包含了全部的MicroPython的功能。

PYB Nano的主要特点: 支持 macroUSB 2路UART 3路I2C 3路SPI 10路ADC 支持RTC 支持后备电池输入 支持USB供电和VIN输入(最高12V) 一个用户按键和一个复位键 带有 4个 LED,LED支持亮度调节功能 带有加速度传感器(MMA7660) 支持USB升级功能 低成本、高性能 开源
应用范围: 教育、学习 电子竞赛 机器人 智能硬件 物联网开发 快速原型设计 创客、DIYer






硬件开发
2016-10-15 22:50:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
AGPS
ublox-AGPS解决方案简介
ublox-AGPS解决方案简介
AGPS定位原理解析
浅谈手机AGPS原理
硬件开发
2016-10-14 14:33:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
In /boot/cmdline.txt Replace "console=tty1" by "console=tty3" to redirect boot messages to the third console. Add "loglevel=3" to disable non-critical kernel log messages. Add logo.nologo to remove logo
1 . 修改文件 sudo pico /boot/cmdline.txt
2 . 替换内容 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty3 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait logo.nologo loglevel=3

硬件开发
2016-10-12 15:46:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
1. MAC从PCI总线收到IP数据包(或者其他网络层协议的数据包)后,将之拆分并重新打包成最大1518Byte,最小64Byte的帧.这个帧里面包括了目标MAC地址、自己的源MAC地址和数据包里面的协议类型(比如IP数据包的类型用80表示).最后还有一个DWORD(4Byte)的CRC码。
2. 以太网MAC芯片的一端接计算机PCI总线,另外一端就接到PHY芯片上,它们之间是通过MII接口链接的。
3. PHY是物理接口收发器,它实现物理层。
4. PHY在发送数据的时候,收到MAC过来的数据(对PHY来说,没有帧的概念,对它来说,都是数据而不管什么地址,数据还是CRC.对于100BaseTX因为使用4B/5B编码,每4bit就增加1bit的检错码),然后把并行数据转化为串行流数据,再按照物理层的编码规则把数据编码,再变为模拟信号把数据送出去.收数据时的流程反之。
5. PHY还提供了和对端设备连接的重要功能并通过LED灯显示出自己目前的连接的状态和工作状态让我们知道。
硬件开发
2016-10-08 15:18:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
晶振32.768KHz Q: 起振不稳定,有时候起振不了 A: 匹配电容15pf - 22pf,选用的是22pf。 可能过大,造成起振困难,所呈现的现象应该为32.768KHz频率偏低。
硬件开发
2016-10-08 10:10:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
gap_params_init()
GAP定义了设备如何发现和建立与其他设备的链接。该函数就是用来设置GAP的参数,设置设备名等。可以从Generic Access Service 中看到设置的这些参数。sd_ble_gap_ppcp_set()中ppcp表示外围设备连接首选参数。这个参数主要是让中央设备在首次连接外设时可以读取他们以及时调整连接参数。或者当当中央设备以后重连该设备,并且保留这些参数,那么就免去连接后可能需要修改连接参数的麻烦。当然也可以通过sd_ble_gap_ppcp_set()来更改连接参数。
conn_params_init()
链接参数更新设置。主要设置什么时候发起更新链接参数请求以及间隔和最大尝试次数。
client characteristic configuration descriptor 客户端特征配置描述符
ble_stack_init()
softdevice_ble_evt_handler_set(ble_evt_dispatch)注册事件派发程序。
因为我的蓝牙需要和苹果的homekit平台对接,所以就拿homekit_init(void)作为添加服务的分析。
homekit整体上可以分为三个部分,uuid的初始化,外设信息初始化和配对初始化。
在uuids_init(void)中通过static const ble_uuid128_t base_uuid = { { HOMEKIT_BASE_UUID } };赋值,然后通过sd_ble_uuid_vs_add(&base_uuid, &uuids_type)函数将自定义的uuid添加到协议栈中。
在void accessoryinfo_init(void),主要是实现了添加服务和特征值。
然后通过service_addService(&service, characteristics)函数将这些服务放到协议栈里。通过函数service_add_characteristic(uint16_t service_handle, const service_characteristic_t* characteristics)来添加服务的特性值。其实其他任何服务添加模板都是一样,这些已是套路。
最后通过函数pairing_init(void)来初始化配对参数。配对的设置整体代码也一样,具体的需要另外章节分析。
然后就到了广播初始化函数advertising_init(void),初始化函数中通过ble_advdata_t结构体来设置广播参数比如:广播的uuid,广播所依赖的homekit版本,还有广播数据等。广播一般有四种类型分别是:通用广播,定向广播,不可连接广播,可发现广播。最后通过函数ble_advdata_set()将这些数据设置进栈。之后就可以通过函数sd_ble_gap_adv_start()来进行广播了。
硬件开发
2016-08-18 09:46:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
Introduction
IAR Embedded Workbench for ARM version 5.50 and later can optionally generate position-independent code and/or position-independent data.
Definition ROPI = Read-Only Position Independence. This concerns everything that is readonly in the ELF output from the linker. Note that this includes const data and data initializers, i.e. typically everything that is put in FLASH. RWPI = Read-Write Position Independence. This concerns everything that is readwrite in the ELF output from the linker. In the present version there is also an option --pi_veneers (position independent veneers, see the Development Guide for further information)
Compiler options
The following description is an excerpt from the Development Guide: Option: --ropi
Use this option to make the compiler generate code that uses PC-relative references to address code and read-only data.
When this option is used, these limitations apply:
* C++ constructions cannot be used
* The object attribute __ramfunc cannot be used
* Pointer constants cannot be initialized with the address of another constant, a string literal, or a function. However, writable variables can be initialized to constant addresses at runtime.
See also --no_rw_dynamic_init (below) and preprocessor symbol __ROPI__
Option: --rwpi
Use this option to make the compiler generate code that uses the offset from the static base register (R9) to address-writable data.
When this option is used, these limitations apply:
* The object attribute __ramfunc cannot be used
* Pointer constants cannot be initialized with the address of a writable variable.
However, static writable variables can be initialized to writable variable addresses at runtime.
See also --no_rw_dynamic_init (below) and preprocessor symbol __RWPI__
Option: --no_rw_dynamic_init
Use this option to disable runtime initialization of static C variables. C source code that is compiled with --ropi or --rwpi cannot have static pointer variables and constants initialized to addresses of objects that do not have a known address at link time. To solve this for writable static variables, the compiler generates code that performs the initialization at program startup (in the same way as dynamic initialization in C++).
Example
In each project where ROPI/RWPI is needed, the application design and development and debugging environment will be unique. The number of different possible use cases and needs of position independent code/data are probably not possible to foresee.
It's difficult to create an exhaustive example that covers all aspects - anyway here is an example trying to show some basics of ROPI and RWPI .
Download the example and follow the instructions in readme.pdf about how to build and run. There is also a STM32F4 Discovery board example .
Note:
You will probably get build errors with newer version of IAR Embedded Workbench for ARM. The solution is to replace static __global_reg char* rwpi_data @ "R9";
with #if (__VER__ < 6020000) static __global_reg char* rwpi_data @ "R9"; #else static __no_init char* rwpi_data @ R9; #endif
硬件开发
2016-08-17 17:24:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
代码来源:https://github.com/dwelch67/raspberrypi/tree/master/bootloader05
前要:po学渣,想造车轮,于是开始了不归路。
树莓派启动流程(照搬github主原文): boots off of an on chip rom of some sort reads the sd card and looks for additional gpu specific boot filesbootcode.bin and start.elf in the root dir of the first partition(fat32 formatted, loader.bin no longer used/required) in the same dir it looks for config.txt which you can do things likechange the arm speed from the default 700MHz, change the address whereto load kernel.img, and many others it reads kernel.img the arm boot binary file and copies it to memory releases reset on the arm such that it runs from the address where the kernel.img data was written.
所以kernel.img会被gpu加载到0x8000的地方,我们要写的代码于是就从这里开始。 file:vectors.s .globl _start _start: b skip .space 0x200000-0x8004,0 ;这里将0x8004到0x200000的数据统统填为0 skip: mov sp,#0x08000000 bl notmain ....
为什么填0x8004,原因是0x8000地址开始是要写一个跳转指令,跳转到skip这边来。
所以, 原理一下子就明晰了 ,写代码然后做成kernel.img给gpu加载到内存0x8000的地方并让cpu去执行。
剩下的就是如何组织代码结构的问题了。
github主的方法是,cpu加载他的代码,然后他的代码配置uart,并等待数据传输进来,然后从0x8000这里开始堆放代码数据,最后执行跳转到0x8000执行您传输的数据。 file:periph.c ....... #define AUX_ENABLES 0x20215004 #define AUX_MU_IO_REG 0x20215040 #define AUX_MU_IER_REG 0x20215044 #define AUX_MU_IIR_REG 0x20215048 #define AUX_MU_LCR_REG 0x2021504C #define AUX_MU_MCR_REG 0x20215050 #define AUX_MU_LSR_REG 0x20215054 #define AUX_MU_MSR_REG 0x20215058 #define AUX_MU_SCRATCH 0x2021505C #define AUX_MU_CNTL_REG 0x20215060 #define AUX_MU_STAT_REG 0x20215064 #define AUX_MU_BAUD_REG 0x20215068 .......
github主说uart地址在0x20215000这里开始, 树莓派的datasheet 却写的是0x7E20 1000(arm pl011)和0x7E21 5000(mini uart)
当然,kernel.img我也没具体运行过,懒。既然mmu也没启用,肯定是github主写错了,要不就是我错了(已解决,看下面的更新)。
然后github主弄了个判断xmodem传输协议(看下面的更新解释)的代码来判断数据传输状态 file:bootloader05.c //SOH 0x01 //ACK 0x06 //NAK 0x15 //EOT 0x04 ....... if(state==0) { if(xstring[state]==0x04) { uart_send(0x06); for(ra=0;ra<30;ra++) hexstring(ra); hexstring(0x11111111); hexstring(0x22222222); hexstring(0x33333333); uart_flush(); BRANCHTO(ARMBASE); break; } } ........
当接受的数据块头标识着EOT(我猜全称是end of transmit)时,就完成数据写入,并反馈,然后跳转执行您发送的数据。
由于我要造轮子,所以研究到这还不够。于是打开了bootloader05.list,并打开kernel.img和vectors.o继续研究。
kernel.img与vectors.o前面一部份相同,原因是kernel.img是vectors.o与其他文件一同链接成的(elf文件格式)然后生成的纯代码块(elf应该是linux下一种软件执行标准)。
kernel.img开头就是FE DF 07 EA,这应该就跳转指令,由于大小端的原因(其实我并不知道具体意思...)实际加载到cpu是EA 07 DF FE,对比bootloader05.list即可分析出来。
然后查表,armv7架构arm指令里跳转指令是b,由于有几种处理器都是32位的,所以有个cond这个值用来判断处理器(这句话我瞎编的,我也不知道是干嘛的)。
但后边的1010确实是A,所以应该就是这个指令。07 DF FE 是imm24,是有符号的值,用来表示当前运行地址指针(不知道是什么指针,先不研究)要偏移的量。
参考过的文章:http://blog.csdn.net/logicworldzju/article/details/8923596
更新:
前面的地址问题,我弄明白了。一共有 三种地址 : ARM virtual addresses (standard Linux kernel only)(这个地址是开启了mmu后的地址) ARM physical addresses(cpu访问的地址,实际访问时的地址) Bus addresses(总线地址,arm总线amba连接外围设备,然后芯片厂商将总线上的设备地址转换给cpu能用的地址去访问)
所以,由于没有开启mmu,实际的设备地址在cpu看来应该是从0x7E00 0000偏移到了0x2000 000。
偏移量为0x5E00 0000,所以mini uart的地址是0x7E21 5000 - 0x5E00 0000 = 0x2021 5000。
关于 XModem协议 : XModem协议介绍:
XModem是一种在串口通信中广泛使用的异步文件传输协议,分为XModem和1k-XModem协议两种,前者使用128字节的数据块,后者使用1024字节即1k字节的数据块。
这里说的异步文件传输,不知道这个异步到底是个什么异步。看了下 这个文章 ,估计是指每块数据块之间不严格限定时间间隔。
硬件开发
2016-08-08 22:57:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
*.lanyus.com及*.qinxi1992.cn下的全部授权服务器已遭JetBrains封杀,只能搭建自己的IntelliJ IDEA授权服务器了。
若资金允许,请点击https://www.jetbrains.com/idea/buy/购买正版,谢谢合作。
1、下载下面的文件
https://drive.google.com/file/d/0Bx7wGDIg2K-7MTJ1TGN1V1IzTVk/view
2. 下载之后解压,共有15个版本,根据自己的系统选择,我用的mac,选择的是IntelliJIDEALicenseServer_darwin_amd64文件
3. 执行文件
sudo ./IntelliJIDEALicenseServer_darwin_amd64
4. 在idea里输入执行之后的地址就完成了。
硬件开发
2016-08-08 09:51:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
1 下载系统安装文件。
http://vx2-downloads.raspberrypi.org/raspbian/images/raspbian-2016-05-31/2016-05-27-raspbian-jessie.zip
会得到一个
2016-05-27-raspbian-jessie.zip文件。
2 解压
解压出来:
2016-05-27 -raspbian-jessie .img文件。

3 烧写
用工具disk imager把 2016-05-27 -raspbian-jessie .img文件,写入到sd卡中。
当然需要pc上有一个sd卡烧写工具。

http://win32-disk-imager.cn.uptodown.com/windows/download
disk Imager工具。

4把sd插入到Raspberry Pi板子上。
并接上显示器,电源。就可以了。
如果没有hdmi接口的显示器,可以买一个hdmi to VGA的转换器。


如果这个三步没有搞出来,请看,
视频教程:
http://v.youku.com/v_show/id_XNzQ5OTA0MDI4.html

硬件开发
2016-07-27 17:52:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
那么现在回到程序上去吧,这个比较适合已经看过一些蓝牙SDK代码。
1,首先协议栈是如何运作的?
协议栈是基于100%的事件驱动,也就是说协议栈向app发送任何数据都是基于事件的。
当设备收到数据,协议栈得到数据处理后,然后将数据打包成一个结构体,并附上事件id,比如BLE_GAP_EVT_CONNECTED,BLE_GATT_EVT_WRITE来分别告诉上层app这个事件结构体代表的事件。
比如BLE_GAP_EVT_CONNECTED代表链接事件,那么这个事件结构体中包含的数据就是连接参数等数据。而BLE_GATT_EVT_WRITE代表写事件,那么结构体中数据就是对端设备写给板子的数据。
根据上图可以明显看出ble_evt_dispatch()函数就是事件派发函数,举个例子:
static void ble_evt_dispatch(ble_evt_t *p_ble_evt)
{
ble_conn_params_on_evt(p_ble_evt);
ble_nus_ble_evt(&m_nus,p_ble_evt);
on_ble_evt(p_ble_evt);
}
连接参数管理处理函数ble_conn_params_on_evt(p_ble_evt);
UART服务时间处理函数ble_nus_ble_evt(&m_nus,p_ble_evt);
通用事件处理函数 on_ble_evt(p_ble_evt);
不同的事件在事件结构体ble_evt_t中通过id来区别。
然后创建一个服务应该添加到哪里?
在main()函数中有一个services_init();这个函数的内部就是添加服务,特征值等代码。
该函数内部其实就是注册了一个回调函数nus_data_handler(该函数会在手机发数据给板子时将数据从电脑串口打印出来)然后再执行真正的初始化函数ble_nus_init。该函数内部又会调用sd_ble_gatts_service_add这个协议栈的api接口来添加服务。后面也会调用 sd_ble_gatts_characteristic_add这个协议栈的api接口来添加特征值。如图所示:

最后手机发送的数据在哪里,如何发送数据给手机?
手机发送给设备的数据是在哪个函数里出来的? 没有函数,协议栈会抛上来一个事件结构体,收到的数据在结构体里。蓝牙数据接收在底层,接收完后会返回事件给上层的ble_evt_dispatch分发函数,他将事件分发给各个服务或者事件处理函数。服务或处理函数会捕获是否存在写事件case BLE_GATTS_EVT_WRITE:存在就做相应处理。BLE的发送数据给手机是有API接口的,即sd_ble_gatts_hvx(),可以通过参数来设置是以通知方式发送还是指示方式发送(通知不需要回复确认,指示需要)。但是手机发过来的数据没有接受函数,因为他是基于事件驱动的。
硬件开发
2016-07-27 11:10:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
蓝牙协议框架体系基本上就是这个图了,有点乱。
然后,我们先从底层开始分析,主要是由基带层和链路管理层组成。
无线连接(RF)通过2.4GHZ无需申请的ISM频段,实现数据的过滤与传输。
基带层提供两种不同的物理链路(同步面向连接链路SCO,异步无连接链路ACL)主要负责跳频和蓝牙数据帧的传输。
LMP负责两个或多个设备链路的建立和拆除及链路的安全和控制,同时他为上层软件模块提供了不同的访问入口。
蓝牙主机控制器HCI:是由基带控制器,连接管理器,控制和时间寄存器等组成。他是蓝牙中软硬之间的接口。上下两层的数据和消息必须通过HCI的解释才能进行。
中间协议层:
中间协议层主要是由逻辑链路控制与适配协议L2CAP(logical link control and adaptation protocol),服务发现协议SDP,线缆替换协议和二进制电话控制协议TCS等功能组成。
L2CAP是核心部分,他是其他协议实现的基础。位于基带之上,向上层提供面向连接和无连接服务。他主要完成数据的拆装,服务质量控制,协议复用,分组的分割与复用。
SDP是一个基于客户/服务器结构的协议。工作于L2CAP层之上,为上层应用程序提供一种机制来发现可用的服务与属性。
RFCOMM是一个仿真有线链路的无限数据仿真协议。他在蓝牙基带上仿真RS-232控制和数据信号,为上层业务提供传送。
TCS定义了用于蓝牙设备之间建立语音和数据呼叫的控制信令。
高端应用层:
高端协议层主要是包括了PPP,TCP UDP,WAP等协议,这里不多介绍。
蓝牙很重要的一个特性就是所有的蓝牙产品无需实现所有的蓝牙规范。为了更加容易保持蓝牙设备之间的兼容,所以采用了profile(不懂!!!)。profile定义了设备如何实现一种连接或应用。有四种基本的profile他们包括GAP/SDAP/SPP/GOEP
属性协议(AP),通用属性规范(GATT) 一般访问应用规范(GAP)。属性协议定义了客户端与服务器端如何发送符合标准的消息。由6种基本操作构成:请求,响应,命令,指示,通知,确认。通用属性规范:定义了如何发现与使用服务,特性与描述符的标准方法。主要有服务,特性的发现,客户端的读写等。一般访问规范:定义了蓝牙设备如何发现和建立与其他设备的连接。他处理一些一般模式的业务和一些安全性问题,同时还处理一些有关连接的业务。
蓝牙协议栈通过软中断将底层事件(收到蓝牙数据,链接成功,收到广播)抛给app,app再捕获自己感兴趣的时间做相应的处理。至于怎么捕获,就是根据switch case语句(你懂的)来的。如图:
应用程序通过_SVC 指令触发异常进入协议栈SVC异常处理函数,然后根据number调用协议栈中预先实现的底层协议处理函数。
而中断实际上是根据中断向量表中中断号进入协议栈相应中断,然后通过中断号的“中断偏移”返回到应用程序的中断处理函数。
协议栈收到底层数据做相应处理后,处理器进入协议栈将evt_id放入事件队列,后执行SWI中断处理函数。然后程序进入应用程序再取出事件并交给事件派发程序(即ble_evt_dispatch()函数)处理。事件派发程序将事件传给相关服务和事件处理任务。
更具体的代码分析,等到二更了,因为我也是菜鸟。。。
硬件开发
2016-07-25 16:42:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
1、签名的意义
为了保证每个应用程序开发者的合法;
防止部分人通过使用相同的Package Name来混淆替换已经安装的程序,从而出现一些恶意篡改;
保证我们每次发布的版本的一致性(如自动更新不会因为版本的不一致而无法安装);
2、如何签名
创建Android工程;
右键工程,选择Export导出;
选择Android下的Export Android Application;
选择Next;
选择新创建签名或者导入已有签名:
填写完成,即可导出。
硬件开发
2016-07-23 22:18:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
  以前一直使用路由器作为openwrt的开发平台,受制于路由器MTK驱动,无法及时更新openwrt版本,一直忍耐至今。现在可以在Vitualbox上搭建,可以尽情的避开硬件驱动带来的烦恼,积极拥抱新版的openwrt。
1.制作镜像
1.1下载镜像
目前最新版本是Chaos Calmer 15.05.1
https://downloads.openwrt.org/chaos_calmer/15.05.1/x86/generic/openwrt-15.05.1-x86-generic-combined-ext4.img.gz
1.2解压下载包
.

1.3转换镜像格式
需要将镜像转换为Vitualbox的VDI格式 VBoxManage convertfromraw openwrt.img openwrt.vdi --format VDI
2.在Vitualbox中创建虚拟机
类型选择Linux,版本选择Linux2.6,内存128M
虚拟磁盘选择刚刚转换好的openwrt.vdi
启动虚拟机
硬件开发
2016-07-15 00:52:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
Banana pi BPI-M64搭载全志 A64 1.2 Ghz四核ARM Cortex A53 64位处理器, GPU采用双核500MHz Mali-400 MP2,具有的1.1 gpixel的吞吐量,让其图形能力远高于X-Box的性能水平
banana pi BPI-M64由最新的64位四核ARM A53 CPU供电,可提供比其他同行的32位开源开发板高出20%~30%的性能.
BPI-M64 主要配置亮点:
*64 位四核 ARM Cortex A53 1.2 Ghz CPU
*Dual core Mali 400 MP2 GPU
*板载2G DDR3内存
* MicroSD卡座,可以从TF卡启动系统
* 板载8G eMMC flash,系统可以烧录到eMMC,从eMMC启动
* 板载WIFI与蓝牙
* 支持IR遥控,2USB接口
* 支持1000M网口
* 支持Linux和Android 6.0系统
硬件接口:
banana pi BPI-M64 硬件规格:
banana pi BPI-M64在线文档:
https://bananapi.gitbooks.io/bpi-m64/content/en/
论坛:
http://www.banana-pi.org http://www.banana-pi.org.cn
硬件开发
2016-07-14 17:16:07
「深度学习福利」大神带你进阶工程师,立即查看>>>
Just a simple bash script wizard to install Arch Linux after you have booted on the official Arch Linux install media.
With this script, you can install Arch Linux with 2 lines of code.
This wizard is maked to install minimum packages (base, grub and optionally efibootmgr).
At the end of this wizard, you can install or launch archdi (Arch Linux Destop Install) to install and configure desktop packages.
archdi project : https://github.com/MatMoul/archdi
You can watch my videos to show how to use it :
https://www.youtube.com/playlist?list=PLytHgIKLV1caHlCrcTSkm5OF2WSVI1_Sq
How to use :
Boot with the Arch Linux image : https://www.archlinux.org/download/
Download the script :
wget archfi.sf.net/archfi
or if sourceforge is down :
wget matmoul.github.io/archfi
And launch the script :
sh archfi
硬件开发
2016-07-14 12:20:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
Qt本身是一个界面框架,虽然也能做很多其它功能,但画图是其主要解决的问题.
Qt只是一个应用程序,意味着其画图实现需要依赖特定操作系统平台,在不同平台需要不同实现.
在Qt5中,为了更好的实现移植性,引入了QPA插件机制,不同的平台使用不同的插件.平台插件需要解决至少两个问题,一是如何画图,如2d,3d,二是往哪里画图,如窗口系统.
在如何画图上,Qt支持基于光栅的2d软件渲染和基于opengl(es)的2d/3d加速渲染,解决了画图问题,如果仅仅时将图形画到屏幕上还不行,还需要指定要画图的窗口,尤其时桌面平台.
在代码库http://code.qt.io/cgit/qt/qtbase.git/tree/src/plugins/platforms 中具有以下几个平台 android cocoa direct2d directfb eglfs haiku integrity ios linuxfb minimal minimalegl mirclient offscreen openwfd qnx windows winrt xcb
除上述几个插件,wayland-egl插件在QtWayland模块提供基于wayland的图形渲染.
在嵌入式linux系统里,由于资源受限,使用x机制实现窗口系统比较浪费资源的,于是有下述解决方案:
EGLFS, LinuxFB , KMS, DirectFB, Wayland
无窗口系统
EGLFS
EGL是opengL(es)和窗口系统的接口,使应用程序可以利用opengL画图并集成在窗口系统中.
eglfs是Qt的一个平台插件,使Qt程序可以利用opengl es画图而无需窗口系统. 这种方式是在支持gpu的嵌入式设备主要采用的方式. 一般需要gpu厂商提供egl和gles驱动模块.
LinuxFB
窗口系统
XCB
即将图形渲染到x窗口
Wayland
即将图形渲染到wayland 合成器窗口
由于wayland依赖egl实现,在一定程度上和硬件平台关联,并且作为一个还不怎么主流的系统,缺乏详细和能及时更新的文档支持,所以目前在linux上构建其支持wayland的环境还时稍有麻烦.
关于Mesa
关于opengl窗口
既然opengl仅用于画图而不包含窗口,那么特定的平台就需要提供给opengl一个接口,从而实现在操作系统的窗口中使用opengl.
不同平台分别如下: WGL – the equivalent Windows interface to OpenGL CGL – the equivalent OS X interface to OpenGL GLX – the equivalent X11 interface to OpenGL AIGLX – an attempt to accelerate GLX
上述接口时opengl和特定平台的接口,而egl是 Khrono 制定的平台独立的opengl es和窗口系统间的接口规范.
Qt可以利用eglfs插件实现直接画图(全屏),或者在有窗口管理系统(如wayland合成器weston或Qtwayland合成器)时,通过窗口画图.前者只能全屏显示一个程序,后者可以实现多进程应用
硬件开发
2016-08-28 01:37:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
3种类别的文件服 务器:ftp服务器(ftp/tftp)、 Samba服务器、NFS服务器。
ftp的客户可以是任意平台,samba是专门针对windows客户,而NFS则是面向linux/unix用户的。 下面是三种服务器的对比情况:
服务器名称 用户客户端平台 使用范围 服务端口
FTP Windows/linux/unix/macOS等 发布网站,文件共享 Tcp/21
Samba Windows 文件共享(网上邻居) Tcp/445,tcp/139
NFS Linux/unix 网站发布,文件共享(mount) Tcp/2049


Linux服务器端安装配置samba
root@FriendlyARM:/var/www/html# apt-get install samba
root@FriendlyARM:/etc/samba# vi smb.conf
在文件最后增加以下4行:
[root]
path=/samba_share
writeable=yes
valid user=root

root@FriendlyARM:/etc/samba# smbpasswd -a root
New SMB password:
Retype new SMB password:
Added user root.
root@FriendlyARM:/etc/samba# smbpasswd -e root
Enabled user root.
root@FriendlyARM:/etc/samba#
root@FriendlyARM:/# mkdir samba_share
Windows 客户端访问操作
在资源管理器中输入: \\linux服务器的IP地址, 随后将弹出登录用户名,密码输入框
注 :
Linux 中共享路径是 /samba_share, Win dows 中看到是关联的用户名 : \\ip 地址 \ 用 户 名。 Windows 中可以先直接输入 : \\IP 地址 然后在弹出的登录界面中录入 U/P
环境信息:
root@FriendlyARM:~#
root@FriendlyARM:~# cat /proc/version
Linux version 3.4.39-h3 (root@wwd-ubuntu) (gcc version 4.6.3 20120201 (prerelease) (crosstool-NG linaro-1.13.1-2012.02-20120222 - Linaro GCC 2012.02) ) #14 SMP PREEMPT Mon Jul 4 10:10:33 CST 2016
root@FriendlyARM:~#
root@FriendlyARM:~#
root@FriendlyARM:~#
root@FriendlyARM:~# cat /proc/cpuinfo
Processor : ARMv7 Processor rev 5 (v7l)
processor : 0
BogoMIPS : 5257.13
processor : 1
BogoMIPS : 5257.13
processor : 2
BogoMIPS : 5257.13
processor : 3
BogoMIPS : 5257.13
Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpv4 idiva idivt
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc07
CPU revision : 5
Hardware : sun8i
Revision : 0000
Serial : 2400503588102c250c8e
root@FriendlyARM:~#
硬件:
FriendlyARM NanoPi NEO
参考: CubieTruck用户手册-炽鸟.pdf
硬件开发
2016-08-21 15:23:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
配置:
root@FriendlyARM:~# cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d
allow-hotplug eth0
auto eth0
# iface eth0 inet dhcp
iface eth0 inet static
address 172.16.82.15
netmask 255.255.0.0
gateway 172.16.85.1
auto eth0:1
iface eth0:1 inet static
address 10.82.10.15
netmask 255.0.0.0
# gateway 10.0.0.1
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
root@FriendlyARM:~#

配置结果:

root@FriendlyARM:~# ifconfig
eth0 Link encap:Ethernet HWaddr b6:67:06:2f:d9:68
inet addr:172.16.82.15 Bcast:172.16.255.255 Mask:255.255.0.0
inet6 addr: fe80::b467:6ff:fe2f:d968/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:30 errors:0 dropped:11 overruns:0 frame:0
TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2224 (2.2 KB) TX bytes:1006 (1.0 KB)
Interrupt:114
eth0:1 Link encap:Ethernet HWaddr b6:67:06:2f:d9:68
inet addr:10.82.10.15 Bcast:10.255.255.255 Mask:255.0.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Interrupt:114
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:176 (176.0 B) TX bytes:176 (176.0 B)

root@FriendlyARM:~# ping 172.16.82.15
PING 172.16.82.15 (172.16.82.15) 56(84) bytes of data.
64 bytes from 172.16.82.15: icmp_seq=1 ttl=64 time=0.345 ms
64 bytes from 172.16.82.15: icmp_seq=2 ttl=64 time=0.183 ms
64 bytes from 172.16.82.15: icmp_seq=3 ttl=64 time=0.136 ms
^C
--- 172.16.82.15 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.136/0.221/0.345/0.090 ms
root@FriendlyARM:~#
root@FriendlyARM:~#
root@FriendlyARM:~#
root@FriendlyARM:~# ping 10.82.10.15
PING 10.82.10.15 (10.82.10.15) 56(84) bytes of data.
64 bytes from 10.82.10.15: icmp_seq=1 ttl=64 time=0.327 ms
64 bytes from 10.82.10.15: icmp_seq=2 ttl=64 time=0.149 ms
64 bytes from 10.82.10.15: icmp_seq=3 ttl=64 time=0.255 ms

环境信息:
root@FriendlyARM:~#
root@FriendlyARM:~# cat /proc/version
Linux version 3.4.39-h3 (root@wwd-ubuntu) (gcc version 4.6.3 20120201 (prerelease) (crosstool-NG linaro-1.13.1-2012.02-20120222 - Linaro GCC 2012.02) ) #14 SMP PREEMPT Mon Jul 4 10:10:33 CST 2016
root@FriendlyARM:~#
root@FriendlyARM:~#
root@FriendlyARM:~#
root@FriendlyARM:~# cat /proc/cpuinfo
Processor : ARMv7 Processor rev 5 (v7l)
processor : 0
BogoMIPS : 5257.13
processor : 1
BogoMIPS : 5257.13
processor : 2
BogoMIPS : 5257.13
processor : 3
BogoMIPS : 5257.13
Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpv4 idiva idivt
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc07
CPU revision : 5
Hardware : sun8i
Revision : 0000
Serial : 2400503588102c250c8e
root@FriendlyARM:~#
硬件:
FriendlyARM NanoPi NEO
硬件开发
2016-08-21 11:44:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
单片机概述
什么是单片机(What is Microcontrollers?)
单片机就是一块集成在硅片上的微处理器、存储器以及各种输入输出接口的芯片,这样一块芯片就具备了计算机的属性,因而被称为单片微计算机。其事就是一块集成芯片,但是这块集成芯片具备特殊的功能,这些功能我们可以靠我们自己编程自定义,编程的目的就是使它的各个引脚在不同的时间可以输出不同的电平,进而控制连接到这个单片机各个脚的外围电路的电气状态。
百度百科:
单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。从上世纪80年代,由当时的4位、8位单片机,发展到现在的300M的高速单片机。
单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。相当于一个微型的计算机,和计算机相比,单片机只缺少了I/O设备。概括的讲:一块芯片就成了一台计算机。它的体积小、质量轻、价格便宜、为学习、应用和开发提供了便利条件。同时,学习使用单片机是了解计算机原理与结构的最佳选择。
单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用电器等。各种产品一旦用上了单片机,就能起到使产品升级换代的功效,常在产品名称前冠以形容词——“智能型”,如智能型洗衣机等。
单片机的标号信息及其封装类型
标号信息,以51内核单片机产品列表为例:
公司 产品
AT(atmel) AT89C51、AT89C52、AT89C53、AT89C55、AT89LV52、AT89S51、、AT89S52、AT89S53等
Phlilips(飞利浦) P80C54、P80C58、P87C54等
Winbond(华邦) W78C54、W87C58、W87E54、W78E58等
Inter(英特尔) i8C54、i8C58、i8L54、i8L58等
Siemens(西门子)
STC
C502-1R、C502-1E等
STC89C51RC、STC89C52RC等

标示举例解释:
STC:前缀,表示芯片为STC公司生产的产品。其它的前缀如AT、i、Winbond、Inter等
8:表示芯片为8051内核
9:表示内部含有Flash E²PROM 存储器。还有80C51中的0表示含有Mask ROM(掩模ROM)存储器,87C51中的7表示含有EPROM存储器(紫外线可擦除ROM)。
C:表示该器件含有CMOS产品。89LV52中的LV和89LE52中的LE都表示该芯片为低电压产品(3.3V电压供电),89S52中的S表示该芯片含有串行下载功能Flash存储器,既具备ISP可在线编程功能。
5:无意义。
8:表示该芯片内部程序存储空间的大小,在51系列中为多少个4KB,8代表32KB。
RR+:DR+表示内部RAM为1280B,RC表示内部的RAM(随机读写存储器)为512B(贝特)。
40:外部晶振最高可接入的大小,表示芯片的外部晶振最高可接入40MHZ。
I:产的级别,I表示工业级,工作温度范围-40~+85°,C表示为商业级,稳定范围为0℃~+70℃.
PDIP:封装类型,PDIP表示为直插式。
1015:表示本芯片的生产日期10年的第15周。
COK816.GD:芯片的制造工艺或处理工艺相关。
描述的不全的可以参阅一下百度百科, 单片机介绍
单片机的外部引脚介绍
单纯的记忆引脚没有任何意义,有些引脚是作为固定的作用有些引脚的作用是是我们编程赋予的,最好的方法就是边学边记。不同的单片机引脚数不一样功能不一样。
以上图51单片机为例,在标示不清时根据如图的标志1芯片缺口摆放单片机,离标志2凹口最近的一个引脚为1脚,即为芯片的P1.0。左边从上至下为1到20脚,一般芯片的GNG(接电源负极)脚就在如图的芯片的左下角,右边从下至上为21脚到40脚,一般芯片的VCC(接电源正极)脚就在如图的芯片的右上角,
电平介绍
单片机的高低电平的依据与单片机的工作电压紧密相关,单片机是一种数字集成芯片,数字电路中只有两种电平:高电平和低电平,如在工作电压为5V的单片机中,高电平为+5V低电平为0V。计算机的串口芯片RS232C电平为负逻辑电平,高电平为-12V低电平为+12V。
常用逻辑电平与TTL、CMOS、LVTTL、ECL、PECL、GTL、RS232、RS422、RS485、LVDS等,其中TTL和CMOS的逻辑电平按照典型电压可分为4类:5V、3.3V、2.5V、1.8V。5V的TLL和CMOS为通用的逻辑电平。3.3V以下的都为低电压逻辑电平。ECL/PECL和LVDS是差分输入/输出,RS232是单端输入/输出。
TTL(晶体管逻辑电平)使用最多是因为数据表示通常采用2进制(我好想没有发现电路中右其它进制的数据表示形式),高电平等价于1低电平等价于0。
二进制与十六进制
数字电路中只有两种电平特性,即高低电平,从而决定了数字电路中使用二进制。在我们的世界中使用的是10进制,逢十进一借一当十是十进制的特点,从幼儿园就开始接触的加减乘除运算。在二进制中我们需要知道的是逢二进一借一当二,十进制的1转换到二进制位1,十进制的2转换为二进制因为已经满二所以需要进一,为10表示。十六进制当然同理,逢十六进一。这几个是在计算机语言中常用的进制,当然还有三四五六七八九进制(不要太当真,嘿嘿)。
在这里附上一张二/十/十六进制表吧
二进制 十进制 十六进制 0001 1 0x01
0010 2 0x02
0011 3 0x03
0100 4 0x04
0101 5 0x05
0110 6 0x06
0111 7 0x07
1000 8 0x08
1001 9 0x09
1010 10 0x0a
1011 11 0x0b
1100 12 0x0c
1101 13 0x0d
1110
1111
14
15
0x0e
0x0f
二进制的逻辑运算
...
单片机51的基础知识介绍
...
硬件开发
2016-06-30 00:26:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
1、创建tag,在项目文件右键,点击open in git shell 打开shell窗口
git tag -a v1.0 -m 'version 1.0' git push --tag

参考: http://www.cnblogs.com/chjw8016/archive/2012/11/08/2760290.html
硬件开发
2016-06-28 12:47:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
我们的设备在测试时发现有个别的主机,主程序DNS解释服务器域名失败。
最直接的表现就是 ping 126.com 显示:
对于这个问题,最直接的方式就是打开 /etc/resolv.conf 文件查看DNS服务器是否设置正确。结果该文件显示: search lan nameserver 127.0.0.1
博主用 strace ping 126.com 命令,分别比较了好的有问题的设备与没问题的设备。将输出信息用 meld 进行对比,结果看到在这里出现分歧:
可见, ping 命令在解释 "126.com" 域名时,是 connect 127.0.0.1:53 服务。而存在问题的一边,connect这个服务被拒绝了。
于是,博主可以分析得到,好的设备一定有一个服务进程bind了53端口,并提供了 DNS 服务。而有问题的设备一定是没有该进程。
博主在好的设备上运行 netstat -nap 找到了该服务:
同时我们又在问题的设备,执行 netstat -nap ,证实,有问题的设备上这个 dnsmasq 服务没有运行起来。
这里,博主查了些资料: Dnsmasq is a Domain Name System (DNS) forwarder and Dynamic Host Configuration Protocol (DHCP) server for small computer networks, created as free software. Dnsmasq has low requirements for system resources, can run on Linux, BSDs, Android and OS X, and is included in most Linux distributions.
博主归纳一下:dnsmasq就是一个DNS与DHCP的轻量级的服务。
由于OpenWrt本身就是一个路由器的系统,其自带 Dnsmasq 服务向其网络下的子网设备提供 DNS 与 DHCP 服务。而我们OpenWrt自身的程序解析域名时,也就向本地的 dnsmasq 请求解析。
那么,现在的问题是:为什么个别设备它的 dnsmasq 启动不起来? 对比好的设备,执行 ps 是能看到 dnsmasq 进程存在的。执行 /etc/init.d/dnsmasq stop 能停止它。这时候再 ping 126.com 它也是通的。为什么?博主查了一下 /etc/resolv.conf 文件,在停止 dnsmasq 之前,它的内容是: search lan nameserver 127.0.0.1
查一旦停止后,它就会变成: # Interface lan nameserver 202.96.128.166 nameserver 202.96.134.133 search bad
这是OpenWrt为了防止 dnsmasq 被停后无法解析域名,所以在停止之前,将其已知的域名服务器写入到 /etc/resolv.conf 文件中来。
相对于有问题的设备,其 /etc/resolv.conf 内容为: search lan nameserver 127.0.0.1
而 dnsmasq 进程并未被启动过(执行 ps 命令,列表中没有 dnsmasq 进程)。于是博主尝试执行: /etc/init.d/dnsmasq start ,然后执行: ps 查看进程。结果,dnsmasq 进程并没有如愿启动起来。 直接执行 dnsmasq 命令就可以启动服务,然后 ping 126.com 也能拼通。
那么问题应该是在 /etc/init.d/dnsmasq 文件中。博主打开 /etc/init.d/dnsmasq 看了一下,太多了,就不想全部贴出来了。相信大家也没有赖心看。下面只是摘要。 /etc/init.d/dnsmasq start 时会执行到: PROG=/usr/sbin/dnsmasq CONFIGFILE="/var/etc/dnsmasq.conf" <略...> start_service() { include /lib/functions config_load dhcp procd_open_instance procd_set_param command $PROG -C $CONFIGFILE -k procd_set_param file $CONFIGFILE procd_set_param respawn procd_close_instance <略...> }
可以了解到,真正执行的启动命令是: /usr/sbin/dnsmasq -C /var/etc/dnsmasq.conf -k
手动执行这个命令,看能否启动 dnsmasq 服务:
如上,出错了。/var/etc/dnsmasq.conf 文件的第11行有重复的关键字。
这是一个重要的线索!打开 /var/etc/dnsmasq.conf 文件:
如上,第11行的关键字为 dhcp-leasefile 。对比好的设备的该文件。经对比,完全一致。
那问题又在哪儿呢? 是不是把 /var/etc/dnsmasq.conf 文件中的11行删除就可以了呢?尝试如此操作,结果还真是可以启动。 但这没有从根本解决问题。
是不是有别的配置文件,也有 dhcp-leasefile 关键字?
打开 /etc/dnsmasq.conf,这个文件与 /var/etc/dnsmasq.conf 完全一样。但是博主尝试用 /etc/dnsmasq.conf 替代 /var/etc/dnsmasq.conf,如下执行: /usr/sbin/dnsmasq -C /etc/dnsmasq.conf -k
结果没有问题,而如果指定的配置文件为 /var/etc/dnsmasq.conf 就有问题。博主很不理解。为了确保这两个文件是同一个,于是: rm /var/etc/dnsmasq.conf cp /etc/dnsmasq.conf /var/etc/dnsmasq.conf /usr/sbin/dnsmasq -C /var/etc/dnsmasq.conf -k
结果:
博主只想说: What a fuck!
同样是配置文件,同样的内容,只是路径变了而已。为什么放 /var/etc/dnsmasq.conf 就会出错?
是不是 dnsmasq 默认就加载了 /etc/dnsmasq.conf ?如果有指定其它的配置文件,它就会出错?
于是: rm /var/etc/dnsmasq.conf mv /etc/dnsmasq.conf /var/etc/dnsmasq.conf /usr/sbin/dnsmasq -C /var/etc/dnsmasq.conf -k
结果:
证实一点,dnsmasq 确实默认加载了 /etc/dnsmasq.conf,不然为什么在我们将文件移走了,会报找不到 /etc/dnsmasq.conf 文件。这也说明了为什么我们强制性指定配置文件为 /var/etc/dnsmasq.conf 时会报重复关键字了。因为 /etc/dnsmasq.conf 也被加载了的。
对比好的设备里的 /etc/dnsmasq.conf 内容,结果发现: # Change the following lines if you want dnsmasq to serve SRV # records. # You may add multiple srv-host lines. # The fields are ,,,, # A SRV record sending LDAP for the example.com domain to # ldapserver.example.com port 289 #srv-host=_ldap._tcp.example.com,ldapserver.example.com,389 # Two SRV records for LDAP, each with different priorities #srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1 #srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2 # A SRV record indicating that there is no LDAP server for the domain # example.com #srv-host=_ldap._tcp.example.com # The following line shows how to make dnsmasq serve an arbitrary PTR # record. This is useful for DNS-SD. # The fields are , #ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services" # Change the following lines to enable dnsmasq to serve TXT records. # These are used for things like SPF and zeroconf. # The fields are ,,... #Example SPF. #txt-record=example.com,"v=spf1 a -all" #Example zeroconf #txt-record=_http._tcp.example.com,name=value,paper=A4 # Provide an alias for a "local" DNS name. Note that this _only_ works # for targets which are names from DHCP or /etc/hosts. Give host # "bert" another name, bertrand # The fields are , #cname=bertand,bert
里面没有一个配置项,与其 /var/etc/dnsmasg.conf 完全不一样。
OK,大致找到问题了。坏设备的 /etc/dnsmasg.conf 有了 /var/etc/dnsmasg.conf 一样的内容。所以,当 dnsmasq 加载完了 /etc/dnsmasg.conf 后再来加载 /var/etc/dnsmasg.conf 就出错了。
将 /etc/dnsmasg.conf 清空即可: rm /etc/dnsmasg.conf touch /etc/dnsmasg.conf
然后,再 /etc/init.d/dnsmasg start ,就成功了。
那为什么坏的主机 /etc/dnsmasg.conf 有内容?而不是像好的设备那样全是注释? 我们去 OpenWrt工程中找答案。 dnsmasg 在工程的如下路径上:package/network/services/dnsmasq/ 目录为: . ├── files │   ├── dhcp.conf │   ├── dnsmasq.conf │   ├── dnsmasq.hotplug │   └── dnsmasq.init ├── Makefile └── patches ├── 001-Build-config-add-DNO_GMP-for-use-with-nettle-mini-gm.patch ├── 002-fix-race-on-interface-flaps.patch ├── 100-fix-dhcp-no-address-warning.patch └── 110-ipset-remove-old-kernel-support.patch 2 directories, 9 files
目录下的 files/dnsmasq.conf 文件在安装后就是 /etc/dnsmasg.conf 文件。打开看,其内容就与好的设备上的 /etc/dnsmasq.conf 文件一致。
如果一个纯净的系统固件,是不会出这个问题的。
那么有两种可能: 由于脚本出错,致将 /var/etc/dnsmasg.conf 文件的内容写入到了 /etc/dnsmasg.conf 中 是我们在进行 sysupgrade 过程中,出错的 /etc/dnsmasg.conf 文件被遗留下来了
验证的方法为:断电重启,看 /etc/dnsmasg.conf 是否会再次变成与 /var/etc/dnsmasg.conf 一致。 结果正常。
好了,博主就分析到这里。这个问题算是已经解决了。
硬件开发
2016-06-25 14:56:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
本文转自迅为4412开发板实战教程书籍: http://www.topeetboard.com


迅为是基于Ubuntu12.04.2平台做开发,所有的配置和编译脚本也是基于此平台,没有在其它平台上测试过。如果你对Linux和Android开发很熟悉,相信你会根据错误提示逐步找到原因并解决,错误提示一般是选用的平台缺少了某些库文件或者工具等原因造成的;建议初学者使用和迅为一致的平台。

Uboot、Kernel以及Android等的编译环境看似复杂,其实只需要抓住以下四个要点。
(1)Uboot、Kernel编译器的安装。编译器在光盘中都有提供,在需要使用的步骤中,会说明编译器在光盘中的位置。
(2)设置环境变量。Uboot、Kernel、QtE、Qtopia编译器的环境变量设置后,编译的时候,系统才能找到编译器。
(3)Android文件系统的编译器。编译器需要使用Ubuntu系统自带的gcc编译器,但是版本不对,所以需要降低版本。迅为将这个过程编写了成几个简单的命令,用户只需要挨个执行命令即可。
(4)库文件。搭建过程中会给通过执行简单的脚本命令来安装库文件,复杂的步骤变的简单有效。
另外,如果用户想了解编译环境具体是怎么搭建起来的,可以利用提供的脚本文件和命令来学习。
1. 使用搭建好的编译环境
两种搭建编译环境的方式,一种方法是用户安装虚拟机,然后安装基础的Ubuntu12.04.2系统,利用迅为提供工具和详细的使用步骤,搭建编译环境;另外一种方法是用户安装虚拟机,然后直接加载“搭建好的Ubuntu镜像”,用户只需要修改一下编译器的环境变量,就可以直接用来编译源码。
以下详细讲解如何搭建编译环境。
需要注意的是,搭建过程中用到的各类软件,都需要和手册提到的版本保持一致,如果使用的是“搭建好的镜像”,则可以跳过这一节,但是编译的时候要针对性的设置一下环境变量。
2. 安装基本软件
Ubuntu系统需要一些基础软件,便于后续使用。
(1)安装虚拟机“Vmware_Workstaion_wm”
(2)然后使用虚拟机安装“Ubuntu12.04.2初始系统”。
(3)安装完成后进入Ubuntu的终端,激活root用户;
(4)接着登录root用户;
(5)虚拟机设置联网、CPU、内存、USB等;
(6)将Ubuntu数据源地址修改为国内163服务器地址;
(7)使用“apt-get update命令”更新数据源;
(8)在Ubuntu安装软件vim,apt-get install vim;
(9)在Ubuntu安装软件ssh,apt-get install ssh。
3. 交叉编译工具
编译的时候需要用到交叉编译工具,本小节介绍如何安装编译Uboot和Kernel的编译工具arm-2009q3。
提供的交叉编译工具是用户光盘“02_编译器以及烧写工具”→“arm交叉编译器”文件夹中的压缩包“arm-2009q3.tar.bz2”。
使用SSH工具将交叉编译工具拷贝到 Ubuntu12.04.2系统的文件夹“usr”-->“local”-->“arm”中,local下默认没有arm文件夹,可以新建一个。
使用命令“cd /usr/local/arm/”进入/usr/local/arm文件夹,然后使用解压命令“tar -vxf arm-2009q3.tar.bz2”解压压缩包。
接着修改交叉编译工具路径,需要修改环境变量。在Ubuntu命令行中,执行命令“cd /root”和“vim .bashrc”,打开环境变量文件“.bashrc”。
如下图所示,在“.bashrc”文件中的最后一行添加如下信息:
“export PATH=$PATH:/usr/local/arm/arm-2009q3/bin”
修改完成后保存退出。执行更新环境变量“source .bashrc”的命令。
最后,在Ubuntu命令行中输入命令“arm”,然后按TAB键,如果在命令行中能够看到arm编译器的信息,就表明交叉编译工具安装成功。如下图所示。
4. 安装库文件、JDK以及降低GCC版本
为了方便用户,我们将库文件和JDK的安装命令制作成了脚本文件,用户只要执行两个脚本就可以安装库文件和JDK。这两个脚本在用户光盘“02_编译器以及烧写工具”→“tools”文件夹下的压缩包“Android_JDK.tar.bz2”中。
用户将压缩包拷贝到Ubuntu系统中,解压压缩包会生成文件夹“Android_JDK”。使用cd命令,进入解压出来的“Android_JDK” -->“jdk6”文件夹。如下图所示,使用命令“./install-sun-java6.sh”运行脚本文件“install-sun-java6.sh”。需要注意的是,这条命令执行完毕可能会耗时15分钟以上。执行脚本的时,根据提示输入对应的选择命令。
前一个脚本运行完毕之后,如下图所示,进入解压出来的文件夹“Android_JDK”中,执行命令“./install-devel-packages.sh”运行脚本“install-devel-packages.sh”,安装库文件,需要注意的是,这条命令可能会耗时40分钟以上。上面脚本执行的时候,需要根据提示输入选择命令。
上面这个脚本执行完毕的时候,要注意一下是否有些库文件提示没有安装。如果发现有库文件没有安装的情况,有可能是网络不好或者下载源丢失。这个时候请使用一下更新下载源的命令”apt-get update“,然后再执行一下上面的两个脚本。
例如,如下图所示,再次运行“./install-devel-packages.sh”之后,如没有提示‘无法安装的库和软件’,那么表明已经安装完整了。
最后介绍降低Android编译器GCC版本的方法。
使用Ubuntu编译Android的时候需要用到Ubuntu系统自带的GCC4.4.7编译器,但是安装的Ubuntu12.04.2版本,它的GCC版本过高,所以这里需将GCC编译器的版本降低到4.4.7。
进入前面解压的文件夹“Android_JDK”中,找到文本“update_gcc.txt”,打开文本“update_gcc.txt”后会看到里面有8条命令,这8条命令需要在Ubuntu命令行中依次执行。
使用命令打开“update_gcc.txt”文件,如下图所示。
在依次执行了这8条命令之后,Ubuntu系统就将gcc的版本降低到4.4.7。使用命令“gcc -v”,可以看到gcc的版本为4.4.7了。
在执行这8条命令时,只有第一条命令会耗时10分钟左右,其它的都会很快完成。需要注意的是,命令一定要依次执行,不能有遗漏。
硬件开发
2016-06-22 16:13:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
这样处理 删除 @val = @{$canned_values{$hz}}; if (!defined(@val)) { @val = compute_values($hz); } output前面加入 $cv = $canned_values{$hz}; @val = defined($cv) ? @$cv : compute_values($hz);
硬件开发
2016-06-20 17:29:00
「深度学习福利」大神带你进阶工程师,立即查看>>>

  PN结中的电荷量随外加电压而变化,呈现电容效应,称为结电容又称为微分电容.结电容影响PN结的工作频率,特别是在高速开关状态时,使其单向导电性 变坏,甚至不能工作,在 深入研究PN结的电容特性后,发现PN结电容是由势垒电容和扩散电容两种性质不同的因素共同造成的.
   1 、势垒电容CB
  PN结交界处形成的势垒区,即空间电荷区,是积累空间电荷的区域,极性不同的电荷分别处于界面两侧(P区和N区),就好象平行板电容器的极板一样。这 两个区域能够存放电荷(载流子),即充电;也能够被取走电荷,即放电。于是,当PN结两端电沍变化时,将引起PN结空间电荷的改变,表现为电容性效 应, 同时引起势垒层的变化,可以用势垒电容GB来描述这种效应。
  当PN结处于正向偏置状态,且正向电压升高时,N E和P K中的多数载流子便进入阻挡层并与其中部分相反极性的空间电荷中和,就好像把这些载流子存 放在空间电荷区一样。这种现象称为载流子的存储效应存储电荷童随正偏座的增加而增加,相当 于栽流子向势垒电容充电。当外加正向电压洚低时,又会有一部分 载流子离开阻挡层,像被从PN结中取出一样,即相当于势垒电容的放电.应当注意,势垒电容不是一个固定不变的值,其大小随外加电压而改变,当外加电压保持 不变时,阻挡层中空间电荷 的数目也保持不变,势垒电容也停止了充放电。可见,势垒电容只在外加电压变化时才起作用,外加电压频率越高,势垒电容的 作用 越显著。势垒电容&的大小与PN结截面积成正比,与阻挡层厚度成反比。
   2、扩散电容CD
  PN结的正向电流是由P区中的空穴和N芪中的电子相互扩散造成的。当PN结外加正向电压时,大量电子由N区进入P区, 空穴由P区进入N区;但电子进 入P区后并不是立即与空穴复合而消失,而是在靠近耗尽层的一定距离内(通常称为扩散长度)一面继续扩散,一面与空穴复合后消失,反之类同,可见在扩散长度 内存储了一定数量的电荷,正向电流越大,存锗电荷越多.它们随正向电压的变化亦具有电容的性质,称为扩散电容CD。
  综上所述,PN结电容Cj的两种成分在不同外加电压条件下所占的份额不同.在正向偏置状态下,当正向电压较低时,因扩散运动较弱,扩散电容比较小,势 垒电容占主要成分;正向电冱较高时,扩散运动加剧,使扩散电容按指数规律上升,成为PN结电容的主要成分。在反向偏置状态下,因扩散运动被抑制,因而表现 出较小的扩散电容,因此结电容以势垒电容为主,如图2-2所示。
硬件开发
2016-06-20 14:42:00
「深度学习福利」大神带你进阶工程师,立即查看>>>

基础篇
http://blog.csdn.net/zhzht19861011/article/category/5950097
高级篇
http://blog.csdn.net/zhzht19861011/article/category/6191478

官方 What is An RTOS WhyUseRTOS
硬件开发
2016-06-18 04:40:00
「深度学习福利」大神带你进阶工程师,立即查看>>>
常用软件的安装keil的安装配置
安装Keil,建议安装Keil4。下载MDK,直接安装即可,然后使用keygen.exe注册机破解。

安装之后,打开Keil,点击菜单栏File进入License Management...

打开之后如下图,复制CID
打开注册机,如下图粘贴到注册机,选择Target,点击Generate生成注册码,然后复制会keil注册栏目中。
如下图,复制后点击AddLlc。注册成功后会用使用到期时间。下图是注册失败提示的错误信息

硬件开发
2016-06-18 00:13:00