精华内容
下载资源
问答
  • 信息系统开发方法-生命周期法

    千次阅读 2020-06-29 21:35:14
    生命周期法就是按照信息系统生命周期的各个阶段划分任务,且每个阶段有相对独立的任务,然后按一定的规则和步骤,有效地进行信息系统开发方法。 生命周期按阶段划分,提出的是组织、管理和控制信息系统开发过程的一...

    1. 生命周期法概念

    生命周期法 就是按照信息系统生命周期的各个阶段划分任务 , 且每个阶段有相对独立的任务 , 然后按一定的规则和步骤,有效地进行信息系统开发的方法。
    生命周期按阶段划分,提出的是组织、管理和控制信息系统开发过程的一种基本框架,原则性地指导两部分工作:
    1. 管理: 强调进程安排、资源分配、评估、控制、反馈
    2. 开发: 强调任务和开发文档

    一般将生命周期法划分为五个阶段,每个阶段有属于自己的任务。

    2.阶段划分

    整体流程如下:

    每个阶段都有属于自己独立的任务,独立的模型来进行合理的系统开发。

    总体的开发流程是先建立属于信息系统的概念模型-->信息系统的逻辑模型—>信息系统的物理模型-->信息系统

    系统规划阶段主要是解决要开发的信息系统“是什么”的问题,即为什么要创建新的信息系统,和老的信息系统相比,新的信息系统的意义是什么,市面上大家使用的信息系统有什么样的优点,新的信息系统和这些信息系统相比又应该是什么样子的。

    核心是可行性分析,技术可行性,法律可行性,经济可行性等多方面进行分析。

    可以使用诺兰阶段模型,三阶段模型进行信息系统规划,使用关键成功因素发,战略目标集转化法,BSP方法,价值链分析法等从业务流程,企业关键成功因素等多方面将信息系统的目标和企业的发展战略结合,达到信息系统为企业发展战略为服务的目的。

    系统分析阶段主要解决开发信息系统“做什么”的问题。这是开发一个信息系统十分关键的一步!做需求分析,最关键的是要将现实师姐的问题转化为计算机世界问题,然后用计算机的办法解决它。如果对方对系统开发了解的话,需求分析很好做,但是如果对方不了解,需求分析就很难进行,这个时间尽量使用模型来解决问题:

     

    模型是现实世界和计算机世界的桥梁;

    此外,还可以使用原型来进行需求分析。

    系统设计算是正式的步入信息系统的开发阶段,系统设计分为总体设计和详细设计阶段。

    总体设计是对信息系统的架构,高层结构等进行设计;即系统的架构即程序的运行模式,层次结构,调用关系,规划具体的实现技术类型等,高层结构指子系统的划分,接口的设计等。即mvc,spring等大家常见的架构,尽量要做到知其所以然。

    详细设计包括很多部分,代码设计,输出设计,输入设计,人机对话设计,模块详细设计,数据库设计、网络设计等

    系统实施阶段包括编码和测试两部分。编码是程序设计及实现的过程,遵循好的编码规范,设计好程序结构即可。

    测试是整个一系列的子过程,单元测试-->集成测试-->验收测试-->系统测试,要记着成功的测试就是发现问题的测试,程序是不可能没有问题的,而80%的问题往往出现在20%的模块,如果在测试中发现了问题,就想着在这些模块继续发掘更多的问题。还要注意设计好的测试用例(覆盖能力足够强,注意测试边界值),使用白盒测试,黑盒测试等共同完成整个测试过程。

    测试完成进行系统切换就完成了整个实施阶段。

    系统维护严格来说已经不算开发过程,主要要做程序,数据库,代码。机器设备四个方面的内容,进行对系统错误的维护(改正性维护),开发新功能的维护(完善性维护),适应新的运行环境的维护(适应性维护),预防将来可能出现问题的维护(预防性维护),最多的是完善性维护,约占整个维护的25%;最少的是预防性维护,仅占不到5%。

    tip:一般来讲,程序员可以分为三类,懂管理的,懂设计的和懂代码的。懂管理的,业务的,架构的做了项目经理,架构师,系统分析与;懂设计的做了高级程序员,算法工程师;懂代码的,程序员。信息系统的开发应该是一个系统工程,是管理+计算机技术两方面的事情(技术可以不那么好,但是要先进,例如云计算,区块链等要熟悉,至少能用,知道优缺点,万一要开发能上手),希望自己将来能做好。

    展开全文
  • django开发个人博客系统

    万次阅读 多人点赞 2019-02-18 22:08:37
    项目简介 运行平台:windows Python版本:3.4 Django版本:2.0 数据库工具:sqlite 开发工具:Pycharm+sublime-text ...写在开头:这是我第一次使用Django进行web开发,...虽然本项目名为信息资源型系统,但是其实...

    目录

    前言
    项目预览
    项目版本
    项目构思
    项目实战
         登录子系统
         后台美化
    完整项目获取
    尾言

    前言

        当初是在2018年写下的这篇文章,那时的django更新到了版本2.0,使用人数还是比较少的,网上的教程大多也很少。而现在随着python web框架的流行,越来越多人开始接触到了django这门技术。如今,django已经更新到了版本3.0,添加了支持异步等重要特性,但是这些特性和本篇文章基本无关。写下这篇文章的初衷是为了让刚接触django框架的童鞋可以入门上手一个项目,了解如何快速搭建一个项目,毕竟python web的优势便是快速易上手嘛【最近接触了springboot后的感触】。如今再次更新这篇博文(2020-2月),希望能够给予大家入门一定的帮助。
        
        
    p.s:其实建立一个web项目需要处理的事情比较杂,我就按照我的建立习惯给大家写下这篇教程。
    另外,本项目是我在重新写时完整重新搭建,所以一定可以跑通,我会写的比较仔细一点,如果你能耐心看完,必定有所收获。
    【-------------------------原创不易,请勿侵权------------------------------------------------------------------】

    项目预览

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
        
        

    项目版本

    运行平台:windows
    Python版本:3.7
    Django版本:3.0
    数据库工具:sqlite
    开发工具:Pycharm+vscode
    依赖:pillow,django-simpleui,django_summernote
        
        

    项目构思

        个人博客系统属于一个非常小型的项目,不会存在高并发的情况,同时注册用户主要也就是为了评论博客内容,其实用户账号安全性也可以完全不用考虑。项目采取前后端分离的形式进行开发,前后端信息交互多数采取ajax形式(按理说动态更新页面比较友好交互,但是为了让大家感受一下这两种方式,在登录这一块采取静态跳转)。剩下的部分一次性在这里写下来大家也不一定能看的很明白,在建立项目的过程中再给大家介绍。
        
        

    项目实战

    请先下载静态文件 下载连接:https://pan.baidu.com/s/1Er2S63MThOfzhlbuUkTEkw 之后替换相应的文件

    我们首先给我们的项目起个名字:Ericam
        
    (1)利用命令行创建项目。
        

    django-admin startproject Ericam
    

        
    (2)创建APP
        
    解释一下:项目中会存在登录子系统,博文管理子系统等,这些子系统每个都可以作为一个app,如此分离方便日后开发维护。但是作为一个入门项目,便不如此麻烦了。我们在整个项目只建立一个app。
    由于我们准备搭建的是一个博客系统,所以就给这个APP起名为:blog
        
    在命令行下继续输入

    python manage.py startapp blog
    

        
    此时文件目录结构:
    在这里插入图片描述
        
    介绍一下各个文件的用处
    在这里插入图片描述
        
    删除test.py,新建一个urls.py文件
    在这里插入图片描述
    为什么需要两个urls.py文件呢?方便分层管理,类似于一级目录,二级目录。
        
        
    (3)注册app并配置静态文件目录
    在这里插入图片描述
        
    在settings.py文件里添加如下内容
        

    # 配置静态文件目录
    STATICFILES_DIRS = [
            os.path.join(BASE_DIR, 'static'),
        ]
    

        
    【静态文件:css,js和图片文件等,我们在这里配置了文件目录路径】
    此时运行项目,用浏览器访问 http://127.0.0.1:8000/
    在这里插入图片描述
    出现一个小火箭代表我们的项目搭建成功了。
        
        
    (4)
    新建文件夹,如下所示(建议直接将static文件夹复制过来,本博客不会讲解css以及js):
    在这里插入图片描述
    (所有html文件存放于templates文件夹下)
    新建index_unlog.html文件【作为首页,未登录时显示的页面】
    我们先简单测试一下,给大家展示一下django如何通过view.py视图层显示html页面。
    在index_unlog.html里:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>首页</title>
    </head>
    <body>
        个人博客系统测试
    </body>
    </html>
    

    在views.py文件里:

    def index_unlog(request):
        return render(request,'index_unlog.html')
    

    最后我们添加一下路由地址,在与settings.py同级目录的urls.py:

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('blog/',include('blog.urls')),
        path('',views.index_unlog,name='index_unlog')
    ]
    

    在新建的urls.py文件【以后我加个标号2代表该文件】里添加如下内容:

    app_name = 'blog'
    urlpatterns = [
    ]
    

    ps:在pycharm里按alt+enter可以添加未引入的类包。
    此时刷新项目,用浏览器访问 http://127.0.0.1:8000/

    在这里插入图片描述

    搞懂了每个文件的大致作用,我们便可以开始正式开发博客系统啦。
    我们按照模块化进行开发。
        
        
        

    登录子系统开发

    (1)首页(未登录)-编写index_unlog.html
        

    {% load static %}
    <html lang="zh">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="author" content="Ericam_">
    
        <!-- CSS -->
    	<title>Ericam_blog</title>
    	<link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}">
    	<link rel="stylesheet" media="screen" href="http://fonts.googleapis.com/css?family=Open+Sans:300,400,700">
    	<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    	<link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}">
    	<!-- Custom styles for our template -->
    	<link rel="stylesheet" href="{% static 'css/bootstrap-theme.css'%}"  >
    	<link rel="stylesheet" href="{% static 'css/log.css'%}">
    	<link rel="stylesheet" href="{% static 'css/blog.css'%}">
    	</head>
    
    
    <body class="back">
      <!--导航栏-->
    	<div class="navbar navbar-inverse navbar-fixed-top headroom" >
    		<div class="container">
    			<div class="navbar-header">
    				<!-- Button for smallest screens -->
    				<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"><span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button>
    				<a class="navbar-brand"><img src="{%static 'css/images/lo.png'%}" alt="Progressus HTML5 template"></a>
    			</div>
    			<div class="nav navbar-nav navbar-right">
    								<!--在这里填写登录提交  1-->
    			</div>
    		</div>
    	</div>
    
    	  <center>
        <div class="container" style="padding-top:300px;min-height:800px">
          <div class="row">,.
            <p class="lead"><font color="white"">个人博客系统,尽情的享用吧(〃'▽'〃)</font></p>
            <p class="tagline"><font color="white">如果您有优秀的建议,欢迎投递哦</font></p>
    							<!--在这里填写登录提交  2-->
          </div>
        </div>
    	</center>
    
    
       <footer id="footer" class="top-space">
    		<div class="footer2">
    			<div class="container">
    				<p class="text-center">Copyright &copy; 2020, Ericam_blog</p>
    			</div>
    		</div>
      </footer>
    </body>
    </html>
    

    第一句话{%load static%}代表引入静态文件(css,js等)
    img,css,js等文件的引用与下述语句类似:

     <link rel="stylesheet" href="{%static 'css/log.css' %}">
    

    此时打开浏览器查看效果:
    在这里插入图片描述
        
        
    (2)登录页-login.html
        

    {%load static%}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
        <link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}">
        <link rel="stylesheet" href="{%static 'css/log.css' %}">
        <link rel="stylesheet" href="{%static 'css/semantic.css' %}">
        <link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}">
    </head>
    <body class="login">
        <div class="ui center aligned grid" style="margin-top: 200px">
            <div class="ui six wide column">
                <h1 class="ui teal header">Ericam blog-登录</h1>
                <div class="ui segment">
                    <div class="ui content">
        <form class="ui large form" method="post" action="{%url 'login'%}">
          <div class="ui stacked segment">
            <div class="field">
              <div class="ui left icon input">
                <input type="text" name="username" placeholder="请输入用户名">
              </div>
            </div>
            <div class="field">
              <div class="ui left icon input">
                <input type="password" name="password" placeholder="请输入密码">
              </div>
            </div>
            {{ error }}<br>
            <a class="pull-right field" >忘记密码</a>
            <button class="ui fluid large teal button" type="submit">登陆</button>
          </div>
    
          <div class="ui error message"></div>
        </form>
    
        <div class="ui message">
          New to us? <a>注册</a>
        </div>
                    </div>
                </div>
            </div>
        </div>
    </body>
    </html>
    

        
    添加路由信息:
        

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('blog/',include('blog.urls')),
        path('',views.index_unlog,name='index_unlog'),
        path('login',views.login,name='login')
    ]
    

        
    添加视图层views.py内容:
        

    def login(request):
        return render(request,'login.html')
    

        
    此时预览:
        
    在这里插入图片描述
        
    在index_unlog.html里添加内容:

    	<!--在这里填写登录提交  1-->
    <a class="btn" href="{% url 'login' %}">登录 / 注册</a></li>
    
        <!--在这里填写登录提交  2-->
    <p><a class="btn btn-action btn-lg" role="button" href="{% url 'login' %}">START NOW</a></p>
    

        
    为了实现登录功能,我们首先需要构造一个用户表
        
    打开models.py文件

    from django.db import models
    from django.contrib import  admin
    from django.urls import reverse
    from django.utils.timezone import now
    
    # Create your models here.
    
    class User(models.Model):
        username = models.CharField(max_length = 50)
        password = models.CharField(max_length = 200)
        nickname = models.CharField(max_length = 50,default='匿名')
        email = models.EmailField()
        created_time = models.CharField(max_length=50,default=now)
        comment_num = models.PositiveIntegerField(verbose_name='评论数', default=0)
        avatar = models.ImageField(upload_to = 'media', default="media/default.png")
    
        def __str__(self):
            return self.username
    
        def comment(self):
            self.comment_num += 1
            self.save(update_fields=['comment_num'])
    
        def comment_del(self):
            self.comment_num -= 1
            self.save(update_fields=['comment_num'])
    
    class UserAdmin(admin.ModelAdmin):
        list_display = ('username','email')
    #修饰器
    

    然后打开命令行

    python manage.py makemigrations
    python manage.py migrate
    

    这便生成了sqlite数据库文件
    在这里插入图片描述
    通过sqliteStudio打开浏览:
    在这里插入图片描述
        
    在views.py文件里编写登录逻辑

    def login(request):
        if request.method == 'POST':
            user_name = request.POST.get('username','')
            pass_word = request.POST.get('password','')
            user = User.objects.filter(username=user_name)  #查看数据库里是否有该用户名
            if user:#如果存在
                user = User.objects.get(username = user_name)#读取该用户信息
                if pass_word==user.password:#检查密码是否匹配
                    request.session['IS_LOGIN'] = True
                    request.session['nickname'] = user.nickname
                    request.session['username'] = user_name
                    return render(request,'index.html',{'user':user})
                else:
                    return render(request,'login.html',{'error': '密码错误!'})
            else:
                return render(request, 'login.html', {'error': '用户名不存在!'})
        else:
            return render(request,'login.html')
    

    因为我们需要记录cookies,所以我们打开settings.py文件,注释该语句
    在这里插入图片描述
    此时登录功能已经实现了。登录成功我们希望页面进行跳转,所以我们需要新建一个index.html

    {% load static %}
    <html lang="zh">
      <head>
        <meta charset="utf-8">
        <title>首页-Ericamblog</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="author" content="Ericam_">
    
        <!-- CSS -->
    	<link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}">
    	<link rel="stylesheet" media="screen" href="http://fonts.googleapis.com/css?family=Open+Sans:300,400,700">
    	<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    	<link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}">
    	<!-- Custom styles for our template -->
    	<link rel="stylesheet" href="{% static 'css/bootstrap-theme.css'%}" media="screen" >
    	<link rel="stylesheet" href="{% static 'css/blog.css' %}">
    	<link rel="stylesheet" href="{% static 'css/log.css' %}">
    </head>
    
    <body class="back">
      <script src = "E:/bootstrap/bootstrap-3.3.7-dist/bootstrap-3.3.7-dist/js/jquery.min.js"></script>
      <!--导航栏-->
    	<div class="navbar navbar-inverse navbar-fixed-top headroom" >
    		<div class="container">
    			<div class="container-fluid">
    			  <div class="navbar-header">
    				<!-- Button for smallest screens -->
    				  <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"><span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button>
    				  <a class="navbar-brand"><img src="{%static 'css/images/lo.png'%}" alt="Progressus HTML5 template"></a>
    			  </div>
    
            <ul class="nav navbar-nav navbar-right">
                <li><a><font size="4" color="white">{{user.nickname}}</font></a></li>
                <li><a href="{%url 'index_unlog'%}"><i class="fa fa-sighout"></i><font size="4">注销</font></a></li>
            </ul>
        </div>
    	</div>
    </div>
    
    	  <center>
        <div class="container" style="padding-top:300px;min-height:800px">
          <div class="row">,.
            <p class="lead"><font color="white"">Easy-Download,这里有好多好多资源喔,尽情的享用吧(〃'▽'〃)</font></p>
            <p class="tagline"><font color="white">如果您有优秀的资源,欢迎投递哦</font></p>
            <p><a class="btn btn-action btn-lg" role="button" href="#">START NOW</a></p>
          </div>
        </div>
    	</center>
    
       <footer id="footer" class="top-space">
    		<div class="footer2">
    			<div class="container">
    				<p class="text-center">Copyright &copy; 2020, Ericamblog</p>
    			</div>
    		</div>
      </footer>
    </body>
    </html>
    

    views.py

    def logsuccess(request):
        return render(request,'index.html')
    

    添加路由信息

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('blog/',include('blog.urls')),
        path('',views.index_unlog,name='index_unlog'),
        path('login',views.login,name='login'),
        path('/log',views.logsuccess,name='login-success')
    ]
    

    手动在数据库中添加一个用户信息
    在这里插入图片描述
    我们进行预览
    在这里插入图片描述
        
        
    完成了登录验证功能后,我们就需要添加注册功能,因为刚才用户的信息是我们手动在数据库内添加的,正常情况下应该是前端页面将内容发送给后端,后端经过处理存储在数据库内。
        
        
    注册模块
        
        
    (1)views.py

    def register(request):
        if request.method =='POST':
            user_name = request.POST.get('username','')
            pass_word_1 = request.POST.get('password_1','')
            pass_word_2 = request.POST.get('password_2','')
            nick_name = request.POST.get('nickname','')
            email = request.POST.get('email','')
            avatar = request.FILES.get('avatar')
            if User.objects.filter(username = user_name):
                return render(request,'register.html',{'error':'用户已存在'})
                #将表单写入数据库
            if(pass_word_1 != pass_word_2):
                return render(request, 'register.html', {'error': '两次密码请输入一致'})
            user = User()
            if avatar:
                user.avatar = 'media/' + user_name + '.png'
                img = Image.open(avatar)
                size = img.size
                print(size)
                # 因为是要圆形,所以需要正方形的图片
                r2 = min(size[0], size[1])
                if size[0] != size[1]:
                    img = img.resize((r2, r2), Image.ANTIALIAS)
                # 最后生成圆的半径
                r3 = int(r2/2)
                img_circle = Image.new('RGBA', (r3 * 2, r3 * 2), (255, 255, 255, 0))
                pima = img.load()  # 像素的访问对象
                pimb = img_circle.load()
                r = float(r2 / 2)  # 圆心横坐标
                for i in range(r2):
                    for j in range(r2):
                        lx = abs(i - r)  # 到圆心距离的横坐标
                        ly = abs(j - r)  # 到圆心距离的纵坐标
                        l = (pow(lx, 2) + pow(ly, 2)) ** 0.5  # 三角函数 半径
    
                        if l < r3:
                            pimb[i - (r - r3), j - (r - r3)] = pima[i, j]
                img_circle.save('blog/static/media/'+user_name+'.png')
            user.username = user_name
            user.password = pass_word_1
            user.email = email
            user.nickname = nick_name
            user.save()
                #返回注册成功页面
            return render(request,'index_unlog.html')
        else:
            return render(request,'register.html')
    

        
        
    代码含义很好理解,就是将前端提交的信息以user对象存储到数据库中,中间一部分代码是将用户提交的头像切割成圆形(无需理解)
        
        
    (2)添加路由信息

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('blog/',include('blog.urls')),
        path('',views.index_unlog,name='index_unlog'),
        path('login',views.login,name='login'),
        path('log',views.logsuccess,name='login-success'),
        path('register',views.register,name='register')
    ]
    

    (3)添加register.html

    {%load static%}
    <!DOCTYPE html>
    <html lang="zh-hans">
    <head>
        <meta charset="UTF-8">
        <title>注册</title>
        <link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}">
        <link rel="stylesheet" href="{%static 'css/log.css' %}">
        <link rel="stylesheet" href="{%static 'css/semantic.css' %}">
    </head>
    <body class="register">
        <div class="ui center aligned grid" style="margin-top: 200px">
            <div class="ui six wide column">
                <h1 class="ui teal header"><font color="black">EricamBlog-用户注册</font></h1>
                <div class="ui segment">
                    <div class="ui content">
                        <form class="ui form" method="post" action="{%url 'register'%}"  enctype="multipart/form-data">
                            <div class="field">
                                <input type="text" name="username" placeholder="请输入用户名"><br>
                            </div>
                            <div class="field">
                                <input type="password" name="password_1" placeholder="请输入密码"><br>
                            </div>
                            <div class="field">
                                <input type="password" name="password_2" placeholder="请确认密码"><br>
                            </div>
                            <div class="field">
                                <input type="text" name="nickname" placeholder="请输入昵称"><br>
                            </div>
                            <div class="field">
                                <input type="text" name="email" placeholder="请输入邮箱"><br>
                            </div>
                            <div>头像<input type="file" name="avatar"></div>
                            {{ error }}<br>
                            <button class="ui fluid large teal button" type="submit">注册</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </body>
    </html>
    

        
        
    现在注册模块已经完成了,但是刚才我们在编写登录页面时没有添加对于注册页面的超链接跳转,现在需要进行添加。
    在login.html里修改如下内容:
    在这里插入图片描述
    此时注册功能已经完成,大家可以自行测试。
        
        
    接下来我们再来添加忘记密码模块。
    正常情况下,忘记密码时应该发送邮件给邮箱,邮箱确认后再填写新密码。这里为了简易操作,便忽略。
    (1)添加views.py内容

    def forget_password(request):
        if request.method == 'POST':
            user_name = request.POST.get('username','')
            email = request.POST.get('email','')
            user = User.objects.filter(username = user_name)
            if user:
                user = User.objects.get(username = user_name)
                if(user.email == email):
                    request.session['user_name'] = user_name
                    return render(request,'reset.html')
                else:
                    return render(request,'forget.html',{'error':'您的用户名和邮箱不匹配!'})
            else:
                return render(request,'forget.html',{'error':'请输入正确的用户名'})
        else:
            return  render(request,'forget.html')
    
    def reset(request):
        if request.method == 'POST':
            pass_word1 = request.POST.get('password1','')
            pass_word2 = request.POST.get('password2','')
            user_name = request.session['user_name']
            user = User.objects.get(username = user_name)
            if pass_word1 == pass_word2:
                user.password = pass_word1
                user.save()
                return render(request,'login.html')
            else:
                return render(request,'reset.html', {'error': '两次密码输入不一致!'})
        else:
            return render(request,'reset.html')
    

    (2)添加forget.html和reset.html
    forget.html

    {%load static%}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>忘记密码</title>
        <link rel="stylesheet" href="{%static 'css/log.css' %}">
        <link rel="stylesheet" href="{%static 'css/semantic.css' %}">
    </head>
    <body class="forget">
        <div class="ui center aligned grid" style="margin-top: 200px">
            <div class="ui six wide column">
                <h1 class="ui teal header">Ericam blog-忘记密码</h1>
                <div class="ui segment">
                    <div class="ui content">
                        <form class="ui form" method="post" action="{%url 'forget'%}">
                            <div class="field">
                                <input type="text" name="username" placeholder="请输入用户名"><br>
                            </div>
                            <div class="field">
                                <input type="text" name="email" placeholder="请输入邮箱"><br>
                            </div>
                            {{ error }}<br>
                            <button class="ui fluid large teal button" type="submit">下一步</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </body>
    </html>
    

        
        
    reset.html

    {%load static%}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>重置密码</title>
        <link rel="shortcut icon" href="{% static 'images/gt_favicon.png' %}">
        <link rel="stylesheet" href="{%static 'css/semantic.css' %}">
        <link rel="stylesheet" href="{%static 'css/log.css' %}">
    </head>
    <body class="reset">
        <div class="ui center aligned grid" style="margin-top: 200px">
            <div class="ui six wide column">
                <h1 class="ui teal header">Ericam blog-重置密码</h1>
                <div class="ui segment">
                    <div class="ui content">
                        <form class="ui form" method="post" action="{%url 'reset'%}">
                            <div class="field">
                                <input type="password" name="password1" placeholder="请输入新密码"><br>
                            </div>
                            <div class="field">
                                <input type="password" name="password2" placeholder="请确认新密码"><br>
                            </div>
                            {{ error }}<br>
                            <button class="ui fluid large teal button" type="submit">确认修改</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </body>
    </html>
    

        
        
    (3)添加路由

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('blog/',include('blog.urls')),
        path('',views.index_unlog,name='index_unlog'),
        path('login',views.login,name='login'),
        path('log',views.logsuccess,name='login-success'),
        path('register',views.register,name='register'),
        path('forget',views.forget_password,name='forget'),
        path('reset',views.reset,name='reset')
    ]
    

        
        
    到了这里忘记密码功能已经完成,最后我们还需要添加一下超链接跳转
    打开login.html文件,修改:
    在这里插入图片描述
        
        
    【至此,登录子系统已经全部完成】

    后台美化

    django默认自带后台管理系统
    创建一个超级管理员账户:

    python manage.py createsuperuser
    

    访问:http://127.0.0.1:8000/admin/
    在这里插入图片描述
    接下来我们对后台进行美化

    pip install django-simpleui
    pip install django_summernote
    

    然后在settings.py添加:

    INSTALLED_APPS = [
        "simpleui",   #添加内容,一定要加在admin前
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'blog',
        'django_summernote'#后台富文本
    ]
    
    SUMMERNOTE_CONFIG = {
        # Using SummernoteWidget - iframe mode
        'iframe': True,  # or set False to use SummernoteInplaceWidget - no iframe mode
    
        # Using Summernote Air-mode
        'airMode': False,
    
        # Use native HTML tags (`<b>`, `<i>`, ...) instead of style attributes
        'styleWithSpan': False,
    
        # Change editor size
        'width': '80%',
        'height': '480',
    
        # Use proper language setting automatically (default)
        'lang': 'zh-CN',
    }
    

    刷新,重新进入admin页面:
    在这里插入图片描述
    给后台添加注册,方便管理数据内容:
    修改admin.py文件

    from django.contrib import admin
    from blog.models import Article,User,Category,Tag,ArticleComment,Message
    from django_summernote.admin import SummernoteModelAdmin
    
    # Register your models here.
    class PostAdmin(SummernoteModelAdmin):
        summernote_fields = ('content')  # 给content字段添加富文本
        list_display = ['article_id', 'title', 'created_time']
        search_fields = ['title']  # 搜索框
        list_filter = ['created_time']  # 过滤器
    
    #ass ArticleAdmin(admin.ModelAdmin):
    class CommentAdmin(admin.ModelAdmin):
        list_display = ['username', 'body', 'title']
        search_fields = ['title']  # 搜索框
    
    
    admin.site.register(Article, PostAdmin)
    admin.site.register(Category)
    admin.site.register(Tag)
    admin.site.register(User)
    admin.site.register(ArticleComment,CommentAdmin)
    

    修改models.py文件(完整版):

    from django.db import models
    from django.contrib import  admin
    from django.urls import reverse
    from django.utils.timezone import now
    
    
    #---------------------------------用户---------------------------------------
    class User(models.Model):
        username = models.CharField(max_length = 50)
        password = models.CharField(max_length = 200)
        nickname = models.CharField(max_length = 50,default='匿名')
        email = models.EmailField()
        created_time = models.CharField(max_length=50,default=now)
        comment_num = models.PositiveIntegerField(verbose_name='评论数', default=0)   #评论数
        avatar = models.ImageField(upload_to = 'media', default="media/default.png")  #用户头像
    
        def __str__(self):
            return self.username
    
        def comment(self):
            self.comment_num += 1
            self.save(update_fields=['comment_num'])
    
        def comment_del(self):
            self.comment_num -= 1
            self.save(update_fields=['comment_num'])
    
    #---------------------------------文章评论---------------------------------------
    class ArticleComment(models.Model):
        body = models.TextField()
        username = models.CharField(max_length=50)
        userimg = models.CharField(max_length=70)
        nickname = models.CharField(max_length=50,default="匿名")
        createtime = models.DateTimeField(verbose_name='创建时间', default=now)
        article = models.CharField(max_length=50)
        title = models.CharField(max_length=50)
        # 使对象在后台显示更友好
        def __str__(self):
            return self.article
    
        class Meta:
            ordering = ['-createtime']
            verbose_name = '评论'  # 指定后台显示模型名称
            verbose_name_plural = '评论列表'  # 指定后台显示模型复数名称
            db_table = "comment"  # 数据库表名
    
        list_display = ('article', 'body')
    
    #---------------------------------博客文章标签---------------------------------------
    class Tag(models.Model):
        name = models.CharField(verbose_name='标签名', max_length=64)
    
        # 使对象在后台显示更友好
        def __str__(self):
            return self.name
    
        class Meta:
            ordering = ['name']
            verbose_name = '标签名称'  # 指定后台显示模型名称
            verbose_name_plural = '标签列表'  # 指定后台显示模型复数名称
            db_table = "tag"  # 数据库表名
    
    #---------------------------------博客文章分类---------------------------------------
    class Category(models.Model):
        name = models.CharField(verbose_name='类别名称', max_length=64)
    
        class Meta:
            ordering = ['name']
            verbose_name = "类别名称"
            verbose_name_plural = '分类列表'
            db_table = "category"  # 数据库表名
    
        # 使对象在后台显示更友好
        def __str__(self):
            return self.name
    
    #---------------------------------博客文章---------------------------------------
    class Article(models.Model):
        STATUS_CHOICES = (
            ('d', '草稿'),
            ('p', '发表'),
        )
        article_id = models.CharField(verbose_name='标号', max_length=100)
        title = models.CharField(verbose_name='标题', max_length=100)
        content = models.TextField(verbose_name='正文', blank=True, null=True)
        status = models.CharField(verbose_name='状态', max_length=1, choices=STATUS_CHOICES, default='p')
        views = models.PositiveIntegerField(verbose_name='浏览量', default=0)
        created_time = models.DateTimeField(verbose_name='创建时间', default=now)
        category = models.ForeignKey(Category, verbose_name='分类', on_delete=models.CASCADE, blank=False, null=False)
        tags = models.ManyToManyField(Tag, verbose_name='标签集合', blank=True)
    
        # 使对象在后台显示更友好
        def __str__(self):
            return self.title
    
        # 更新浏览量
        def viewed(self):
            self.views += 1
            self.save(update_fields=['views'])
    
        # 下一篇
        def next_article(self):  # id比当前id大,状态为已发布,发布时间不为空
            return Article.objects.filter(id__gt=self.id, status='p', pub_time__isnull=False).first()
    
        # 前一篇
        def prev_article(self):  # id比当前id小,状态为已发布,发布时间不为空
            return Article.objects.filter(id__lt=self.id, status='p', pub_time__isnull=False).first()
    
        class Meta:
            ordering = ['-created_time']  # 按文章创建日期降序
            verbose_name = '文章'  # 指定后台显示模型名称
            verbose_name_plural = '文章列表'  # 指定后台显示模型复数名称
            db_table = 'article'  # 数据库表名
            get_latest_by = 'created_time'
    
    

    记得使用python manage.py migrate进行生成数据库文件。
    此时访问后台:
    在这里插入图片描述
    写文章时富文本工具也加载了出来:
    在这里插入图片描述

    完整项目获取

    重构了代码,同时更新了博客内容,关键难点已经写下来了。
    如果有问题欢迎在评论区提问。
    如果想要获取完整项目,请扫码赞助该项目。
    获取方式:扫码赞助9.9,留言邮箱地址。
    在这里插入图片描述

    尾言

    其他子模块和该模块大同小异,暂时就不写了。
    其中评论提交和删除采取的是ajax交互形式。
    如果大家看了觉得有帮助请点赞,为了大家重新写了这篇文章,同时重构了代码,确保一定能跑通。

     

    展开全文
  • 为企业或个人在.NET环境下快速开发信息系统提供了强大的支持,开发人员需要开发系统的基础功能和公共模块,平台本身提供了强大的函数库和开发包,开发人员只须集中精力专注自身业务各部分的开发,大大提高开发...

    RDIFramework.NET ━ .NET快速信息化系统开发框架

    第1章 引言

     

    1章 引言

      经过长期的不断改进维护,通过在多个软件项目,多位商业用户的实战考验,能满足不同规模软件项目的快速开发、快速整合、快速实施、灵活配置与管理的要求。为企业或个人在.NET环境下快速开发信息化系统提供了强大的支持,开发人员不需要开发系统的基础功能模块和公共模块,框架本身提供了强大的函数库和开发包,开发人员只须集中精力专注自身业务部分的开发,大大提高开发效率和节约开发成本。

     1.1 文档目的

      本文档为《RDIFramework.NET(.NET快速信息化系统开发整合框架)》产品使用说明书。

      编写本使用说明书的目的是充分叙述RDIFramework.NET框架所能实现的功能及其运行环境,以便使用者了解本软件的使用范围和使用方法,并为软件的维护和更新提供必要的信息。 

     1.2 产品对象与用户群体

      一、中小型软件开发公司,技术支持、技术咨询公司。

      统一的权限、模块分配,授权机制,多数据库开发的支持,多个常用商业控件集,统一的升级部署等。可成为众多中小型软件开发、技术支持、咨询公司项目的配套工具,应用开发的标准参考模型,提高开发效率,节约开发的人力、物力等成本,专注于自身业务。

      二、管理类软件开发者。

      管理类软件开发人员随着自己技术能力、业务能力等提升,难免不会在外面接点私活,对于客户提出的项目要求利用《.NET快速信息化系统开发整合框架(RDIFramework.NET)》你可以只专注其业务要求,开发完成,几分钟即可部署到此平台上,快速简单,安全可靠,又专业。

      三、想进一步提升自身技术能力的开发者、学生等。

      你想提升自身的技术实力吗?你想在职业生涯快速提升吗?你想学习实际的大型商业项目吗?此平台就是你的选择。此平台设计严谨、编码规范、简单易读、同时其通用性与规范性,是作为学习研究的佳品。作为学生、刚出生社会的开发人员或想提升自身开发实力的人,本平台的编码规范,数据库设计思想、分层理念、RBAC授权机制、设计模式、面向服务的开发思想、商业控件开发方法、统一的升级部署等等都值得你参考学习。

      四、培训机构。

      对于培训机构,一个好的培训项目不仅可以让培训的学子受益匪浅,让其培训后方可直接投入实际的工作之中,同时也能提升培训机构的自身品牌。不仅可大大的节省培训成本,更重要是的可以缩短培训周期,让培训学子快速进入工作状态。

      五、政府机关、事业单位。

      对于很多政府机关单位,其内部都有自己的开发团队,他们专注自身业务的同时,若能有一套可把多个系统统一高效、方便的部署到一个平台下,实现统一的管理显得尤为重要。选择一个合适的,安全可靠的,实际使用效果良好的平台非常重要。《.NET快速信息化系统开发整合框架(RDIFramework.NET)》就是你的选择。

      六、企业、工厂等。

      随着信息时代的高速发展,一个企业,工厂等信息化的建设已成为不能忽视的一环。

      不管是企业、工厂,都不止一套管理系统,这些分散的系统很难管理,数据分散不一,集成困难等,如果把这些系统统一的部署到一个平台下,那些这些诸多问题都可迎刃而解。最大程度避免重复开发、反复原地踏步,最大限度使内部的产品、项目等各功能模块之间有更高的兼容性。

     1.3 参考资料

     

     1.4 术语与缩写词

      1) RBAC:基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的代替受到广泛的关注。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。

      2) 角色:角色(Role)为RBAC(基于角色的访问控制Role-Based Access Control)模型中的基本元素。 角色是权限分配的单位与载体。角色通过继承关系支持分级的权限实现。我们通过对角色分配访问权限控制,然后对用户或者用户组分派角色来实现用户的访问权限控制。

      3) 用户权限:就是用户的权利,即用一个帐户登录后,那些功能可以使用,那些功能无法使用,这就是管理员对其设置的权限,只有附合权限的人才可以使用对应的功能。权限就是权利的限制范围。

      4) 角色权限:与用户权限相对应,即为角色的权利。

      5) 用户(User):能够使用应用的唯一身份的人。

        角色(Role:一定数量的权限的集合,权限的载体。

        组织机构(Organize:企业管理中企业分层的基本单元,在本系统中机构只支持单树模型一个企业只有一个根机构(总部),除开根机构其他机构只有一个父机构,可以有多个子机构。

        岗位(Position:一个企业的某个部门的职位(相当于在部门下有相同职能的员工的集合),它隶属于某个具体的部门,并且可以有一个或者多个员工在岗位上任职。

        员工(Staff):企业中的人员,一个人员属于一个机构,一个人员可以关联一个用户。

      6) 操作权限:抽象为什么资源有什么权限,操作权限包括用户、角色、组织机构有什么权限。

      7) 数据权限:数据集权限抽象为什么对象对什么资源有什么权限,数据权限包括模块权限、管理范围、授权范围、资源权限、表权限、列权限、数据集权限。数据集权限主要是通过约束条件实现的记录级权限。

      8) 其他。 


    作者: EricHu
    出处: http://blog.csdn.net/chinahuyong
    Email: 406590790@qq.com
    QQ 交流:406590790 
    平台博客:http://blog.csdn.net/chinahuyong
             http://www.cnblogs.com/huyong
    关于作者:高级工程师、信息系统项目管理师、DBA。专注于微软平台项目架构、管理和企业解决方案,多年项目开发与管理经验,曾多次组织并开发多个大型项目,精通DotNet,DB(SqlServer、Oracle等)技术。熟悉Java、Delhpi及Linux操作系统,有扎实的网络知识。在面向对象、面向服务以及数据库领域有一定的造诣。现从事DB管理与开发、WinForm、WCF、WebService、网页数据抓取以及ASP.NET等项目管理、开发、架构等工作。
    如有问题或建议,请多多赐教!
    本文版权归作者和CNBLOGS博客共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过邮箱或QQ 联系我,非常感谢。


    展开全文
  • 嵌入式系统开发

    千次阅读 2011-09-28 14:57:55
    ********************************LoongEmbedded******************************** 作者:LoongEmbedded(kandi) 时间:2011.9.27 类别:嵌入式系统开发 ********
     
    ********************************LoongEmbedded********************************
    

    作者:LoongEmbedded(kandi)

    时间:2011.9.27

    类别:嵌入式系统开发

    ********************************LoongEmbedded********************************

     

    1. 嵌入式系统开发流程

    1.1  嵌入式系统的概念

    嵌入式系统的定义有很多种,其中国内普遍认同的嵌入式系统定义为:以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统。

     

    我们尝试着进一步理解这个定义:

    1) 以应用为中心

    表示嵌入式系统应该根据不同的应用场合来设计,比如,如果我们要开发智能手机,那么此嵌入式系统的操作系统就应该选择专用的操作系统,比如android操作系统;PowerPC架构的嵌入式处理器一般用于高端服务器,而ARM架构的嵌入式处理器一般用于个人消费电子、汽车电子等。

     

    2) 以计算机技术为基础

    计算机技术包括:运算方法的基本原理与运算器设计、指令系统、中央处理器(CPU)设计、流水线原理及其在CPU设计中的应用、存储体系、总线与输入输出,而嵌入式处理器也就是嵌入式系统的CPU,也有自己的指令系统、流水线原理等,嵌入式系统中的操作系统和应用软件,这是需要编程语言、软件工程等计数机技术作为基础的,但嵌入式系统和微处理器技术、电子技术、通信技术的关系一样很紧密,所以可以知道嵌入式系统是多学科综合的结合体。

     

    3) 软硬件可裁剪

    嵌入式系统由软硬件组成,而且根据不同的应用场合,我们可以根据需要来裁剪软硬件。

     

    4) 适应应用系统对功能、可靠性、成本、体积、功耗等严格要求

    对功能要求的满足肯定是必须的,可靠性要求系统在一定时间内、在一定条件下无故障地执行指定功能的能力或可能性,比如某款GPS产品在室温下连续播放视频不会出现花屏或者死机,可靠性一般分为耐久性、可维修性和设计可靠性,其中设计可靠性是产品质量的关键。

     

    1.2 嵌入式系统的组成

    从功能的角度来分看,嵌入式系统由硬件层、中间层、操作系统层和应用软件层组成。

    图1嵌入式系统结构图

    1.2.1 硬件层

    嵌入式系统硬件层的核心是嵌入式处理器。

    1)   嵌入式处理器

    嵌入式处理器分为嵌入式微控制器(Micro Control Unit,MCU)、嵌入式DSP处理器(Digital Signal Processor,DSP)、嵌入式微处理器(Micro Processor Unit,EMPU)和嵌入式片上系统(System On Chip,SOC)。

     

    ⑴嵌入式微控制器

    嵌入式微控制器的典型代表是单片机,单片机把具有数据处理能力的中央处理器(CPU)、随即存储器RAM、只读存储器ROM、多种I/O和中断系统、定时器/计时器、看门狗、A/D转换等功能及外设集成在一块芯片中。微控制器的最大特点是单片化,体积大大减少,从而使功耗和成本下降、可靠性提高。如INTEL公司的MCS8051就是微控制器。

     

    ⑵嵌入式DSP处理器

    DSP处理器一种独特的微处理器,是以数字信号来处理大量信息的器件。其工作原理是接收模拟信号,转换为0或1的数字信号。再对数字信号进行修改、删除、强化,并在其他系统芯片中把数字数据解译回模拟数据或实际环境格式。它不仅具有可编程性,而且其实时运行速度可达每秒数以千万条复杂指令程序,远远超过通用微处理器,是数字化电子世界中日益重要的电脑芯片。它的强大数据处理能力和高运行速度,是最值得称道的两大特色。如TI的TMS320C62X就是一款DSP处理器。

     

    DSP处理器有一个很重要的应用趋势就是和微处理器的融合,比如TI的OMAP3530就是把一个ARM的cortex A8内核和一个DSP内核,也意味着控制和数字信号的结合。

    ⑶嵌入式微处理器

    嵌入式微处理器(Microprocessor Unit,MPU)由通用计算机中的CPU演变而来。与通用计算机中的CPU不同的是,在嵌入式应用中,将微处理器装配在专门设计的电路板上,只保留和嵌入式应用紧密相关的功能硬件,去除其他的冗余功能部分,这样就以最低的功耗和资源实现嵌入式应用的特殊要求。此外,为了满足嵌入式应用的特殊要求,嵌入式微处理器在工作温度、抗电磁干扰、可靠性等方面相对通过通用计算机中的CPU都做了各种增强,这也是我们选择微处理器需要考虑的一些很重要的因素。比如三星的S3C6410就是一款嵌入式微处理器。

     

    嵌入式微处理器的体系结构可以采用冯·诺依曼体系或哈佛体系结构,其中冯·诺依曼体系定义了单一的存储器空间用于存放指令和数据,而哈佛体系结构定义了单独的存储器空间,分别用于存放指令和数据,这样可以增加了单位时间内能够处理的数据量;指令系统可以选用精简指令系统(Reduced Instruction Set Computer,RISC)和复杂指令系统CISC(Complex Instruction Set Computer,CISC)。RISC计算机在通道中只包含最有用的指令,确保数据通道快速执行每一条指令,从而提高了执行效率并使CPU硬件结构设计变得更为简单。  

     

     

    那么微控制器和微处理器的主要差别在于下面几个方面:

    ①硬件架构方面

    微处理器是一个单芯片CPU,而微控制器则在一块集成电路芯片中集成了CPU和其他电路,构成了一个完整的微型计算机系统。

     

    ②应用领域

    微处理器通常作为微型计算机系统中的CPU使用。其设计正是针对这样的应用,这也是微处理器的优势所在。然而,微控制器通常用于面向控制的应用。其系统设计追求小型化,尽可能减少元器件数量。在过去,这些应用通常需要用数十个甚至数百个数字集成电路来实现。使用微控制器可以减少元器件的使用数量,只需一个微控制器、少量的外部元件和存储在ROM中的控制程序就能够实现同样的功能。微控制器适用于那些以极少的元件实现对输入/输出设备进行控制的场合,而微处理器适用于计算机系统中进行信息处理。

     

    ③指令集特征

    由于应用场合不同,微控制器和微处理器的指令集也有所不同。微处理器的指令集增强了处理功能,使其拥有强大的寻址模式和适于操作大规模数据的指令。微处理器的指令可以对半字节、字节、字,甚至双字进行操作。通过使用地址指针和地址偏移,微处理器提供了可以访问大批数据的寻址模式。自增和自减模式使得以字节、字或双字为单位访问数据变得非常容易。

     

    ⑷嵌入式片上系统

    嵌入式SOC是指在嵌入式系统中广泛应用的,有专门应用范围的SOC芯片,指的是在单个芯片上集成一个完整的系统,对所有或部分必要的电子电路进行包分组的技术。所谓完整的系统一般包括中央处理器、存储器、以及外围电路等。SoC是与其它技术并行发展的,如绝缘硅(SOI),它可以提供增强的时钟频率,从而降低微芯片的功耗。如TI的TMS320TCI6616就是一款嵌入式SOC芯片。

     

    2)   存储器

    嵌入式系统需要存储器来存放和执行代码。嵌入式系统的存储器包含Cache、主存和辅助存储器。

     

    ⑴    Cache

    Cache是一种容量小、速度快的存储器阵列它位于主存和嵌入式微处理器内核之间,存放的是最近一段时间微处理器使用最多的程序代码和数据。在需要进行数据读取操作时,微处理器尽可能的从Cache中读取数据,而不是从主存中读取,这样就大大改善了系统的性能,提高了微处理器和主存之间的数据传输速率。Cache的主要目标就是:减小存储器(如主存和辅助存储器)给微处理器内核造成的存储器访问瓶颈,使处理速度更快,实时性更强。

      

    在嵌入式系统中Cache全部集成在嵌入式微处理器内,可分为数据Cache、指令Cache或混合Cache,Cache的大小依不同处理器而定。一般中高档的嵌入式微处理器才会把Cache集成进去,cache实际就是SRAM。

     

    ⑵主存

    主存是嵌入式微处理器能直接访问的寄存器,用来存放系统和用户的程序及数据。它可以位于微处理器的内部或外部,其容量为256KB~1GB,根据具体的应用而定,一般片内存储器容量小,速度快,片外存储器容量大。  

     

    常用作主存的存储器有:  

    ROM类 NOR Flash、EPROM和PROM等。  

    RAM类 SRAM、DRAM和SDRAM等。  

    其中NOR Flash 凭借其可擦写次数多、存储速度快、存储容量大、价格便宜等优点,在嵌入式领域内得到了广泛应用。

     

    ⑶辅助存储器

    辅助存储器用来存放大数据量的程序代码或信息,它的容量大、但读取速度与主存相比就慢的很多,用来长期保存用户的信息。  嵌入式系统中常用的外存有:硬盘、NAND Flash、CF卡、MMC和SD卡等。

     

    3)   通用设备接口和I/O接口

    目前嵌入式系统中常用的通用设备接口有A/D(模/数转换接口)、D/A(数/模转换接口),I/O接口有RS-232接口(串行通信接口)、Ethernet(以太网接口)、USB(通用串行总线接口)、音频接口、VGA视频输出接口、I2C(现场总线)、SPI(串行外围设备接口)和IrDA(红外线接口)等。

     

    1.2.2中间层

    硬件层与软件层之间为中间层,也称为硬件抽象层(Hardware Abstract Layer,HAL)或板级支持包(Board Support Package,BSP),它将系统上层软件与底层硬件分离开来,使系统的底层驱动程序与硬件无关,上层软件开发人员无需关心底层硬件的具体情况,根据BSP 层提供的接口即可进行开发。该层一般包含相关底层硬件的初始化、数据的输入/输出操作和硬件设备的配置功能。

     

    BSP具有以下两个特点。  

    1)   硬件相关性

    因为嵌入式实时系统的硬件环境具有应用相关性,而作为上层软件与硬件平台之间的接口,BSP需要为操作系统提供操作和控制具体硬件的方法。

     

    2)   操作系统相关性

    不同的操作系统具有各自的软件层次结构,因此,不同的操作系统具有特定的硬件接口形式。 

     

    实际上,BSP是一个介于操作系统和底层硬件之间的软件层次,包括了系统中大部分与硬件联系紧密的软件模块。设计一个完整的BSP需要完成两部分工作:嵌入式系统的硬件初始化以及BSP功能,设计硬件相关的设备驱动。  

    1)   嵌入式系统硬件初始化 

     

    初始化过程可以分为3个主要环节,按照自底向上、从硬件到软件的次序依次为:片级初始化、板级初始化和系统级初始化。  

     

    ⑴片级初始化  

    完成嵌入式微处理器的初始化,包括设置嵌入式微处理器的核心寄存器和控制寄存器、嵌入式微处理器核心工作模式和嵌入式微处理器的局部总线模式等。片级初始化把嵌入式微处理器从上电时的默认状态逐步设置成系统所要求的工作状态。这是一个纯硬件的初始化过程。  

     

    ⑵板级初始化  

    完成嵌入式微处理器以外的其他硬件设备的初始化。另外,还需设置某些软件的数据结构和参数,为随后的系统级初始化和应用程序的运行建立硬件和软件环境。这是一个同时包含软硬件两部分在内的初始化过程。 

     

    ⑶系统初始化  

    该初始化过程以软件初始化为主,主要进行操作系统的初始化。BSP将对嵌入式微处理器的控制权转交给嵌入式操作系统,由操作系统完成余下的初始化操作,包含加载和初始化与硬件无关的设备驱动程序,建立系统内存区,加载并初始化其他系统软件模块,如网络系统、文件系统等。最后,操作系统创建应用程序环境,并将控制权交给应用程序的入口。

     

    2)   硬件相关的设备驱动程序  

    BSP的另一个主要功能是硬件相关的设备驱动。硬件相关的设备驱动程序的初始化通常是一个从高到低的过程。尽管BSP中包含硬件相关的设备驱动程序,但是这些设备驱动程序通常不直接由BSP使用,而是在系统初始化过程中由BSP将他们与操作系统中通用的设备驱动程序关联起来,并在随后的应用中由通用的设备驱动程序调用,实现对硬件设备的操作。与硬件相关的驱动程序是BSP设计与开发中另一个非常关键的环节。

     

    1.2.3操作系统层

    嵌入式操作系统在系统实时高效性、硬件的相关依赖性、软件固化以及应用的专用性等方面具有较为突出的特点,是相对于一般操作系统而言的,它除具有了一般操作系统最基本的功能,如任务调度、同步机制、中断处理、文件处理等外,还有以下

     

    1)    可裁剪性,支持开放性和可伸缩性的体系结构。

     

    2)强实时性,EOS实时性一般较强,可用于各种设备控制中。

     

    3)统一的接口,提供设备统一的驱动接口。

     

    4)操作方便、简单、提供友好的图形GUI和图形界面,追求易学易用。

    提供强大的网络功能,支持TCP/IP协议及其他协议,提供TCP/UDP/IP/PPP协议支持及统一的MAC访问层接口,为各种移动计算设备预留接口。

     

    5)强稳定性,弱交互性。嵌入式系统一旦开始运行就不需要用户过多的干预、这就要负责系统管理的EOS具有较强的稳定性。嵌入式操作系统的用户接口一般不提供操作命令,它通过系统的调用命令向用户程序提供服务。

     

    6)固化代码,在嵌入式系统中,嵌入式操作系统和应用软件被固化在嵌入式系统计算机的ROM中。

     

    7)更好的硬件适应性,也就是良好的移植性。

     

    目前应用比较广泛的嵌入式操作系统有VxWorks、WINCE、LINUX、android等,

     

    1.2.4应用软件层

    应用软件层主要是通过操作系统提供的提供的API接口来调用驱动来控制外围设备,这就是所谓的系统调用。因为是基于操作系统来开发应用,所以需要熟悉操作系统和驱动的一些架构。

     

    1.3 嵌入式系统开发流程

    图2 嵌入式系统开发流程图

     

    嵌入式系统开发的流程可分为下面几部分:

    1)    需求分析

    确定设计任务和目标,并制定说明规格文档,作为下一步设计的指导和验收标准。需求分析往往要与用户反复交流,以明确系统功能需求,性能需求,环境、可靠性、成本、功耗、资源等需求。

     

    2)    体系结构设计

    体系结构设计是嵌入式系统的总体设计,它需要确定嵌入式系统的总体构架,从功能上对软硬件进行划分。在此基础上,确定嵌入式系统的硬件选型(主要是处理器选型),操作系统的选择和开发环境的选择。

     

    3)    硬件/软件协同设计

    在这一阶段要确定硬件部分的各功能模块及模块之间的关联,并在此基础上完成元器件的选择、原理图绘制、印刷电路板(PCB)设计、硬件的装配与测试、目标硬件最终的确定和测试。

     

    4)    系统集成和调试

    将测试完成的软件系统装入制作好的硬件系统中,进行系统综合测试,验证系统功能是否能够正确无误地实现,最后将正确的软件固化在目标硬件中。本阶段的工作是整个开发过程中最复杂、最费时的,特别需要相应的辅助工具支持。

     

    5)    系统测试

    测试最终完成的系统性能是否满足设计任务书的各项性能指标和要求。若满足,则可将正确无误的软件固化在目标硬件中;若不能满足,在最坏的情况下,则需要回到设计的初始阶段重新进行设计方案的制定。

     

    2.  需求分析

    需求分析是在项目开始时最先开始的工作,主要是分析、确认用户的需求。

     

    2.1 分析和确认用户的需求

    2.1.1 分析用户对产品的需求

    通过与客户进行交流来了解客户需要开发什么样的产品,包括产品的功能、性能、价格、开发时间等一系列的问题。描述产品需求的文档通常是由嵌入式系统的总设计者从用户的视角来写的,由一系列的用户需要。

     

    客户对嵌入式系统的理解是建立在想象的基础之上的,对系统的要求可能有一些不切实际的期望,或者是使用他们自己的语言而不是专业术语来表达其需求。由于客户关于所需要系统的描述与设计师所需要的信息之间存在一些差异,所以我们需要用他们的语言来描述用户的需求,而不要用工程型的术语。

     

    客户对产品的需要一般分为功能部分和非功能部分,功能部分描述产品的用途和完成的功能,非功能部分包含以下几点:

    1)   性能

    主要是指系统的处理速度。

    2)   价格

    这是决定我们所选择的开发方案的一个主要的因素。

    3)   产品的尺寸和重量

    4)   功耗

    功耗问题在需求阶段可以以电池供电时系统的工作时间(比如正常工作5个小时)提出来,也可以以系统的总功耗提出来,比如要整个系统的功耗控制800mAh之内。

     

    2.1.2 罗列并确认用户的需求

    对于客户的需求,嵌入式系统设计师要罗列出来并且形成文档来和客户进一步沟通和确认,只有确认这些需求是满足客户要求的滞后才能开始体系结构设计。在罗列并和客户确认的过程中,一定要把客户的需求描述清楚,而且要把客户潜在的需求考虑进来。我们在开发过程中很有可能遇到客户提出新的需求,这是我们不愿意看到的,因为这会给我们的设计带来很大的麻烦,不仅添加研发和生产成本,也会延迟我们的开发时间,所以如果能在需求分析阶段能够把客户潜在的需要提出来,这是最好的。

     

    要建立一个能满足客户预期要求的产品,必须从各个方面来考虑项目,并且要问很多问题,这也是能让设计者的思维细致化的问题,比如下面的问题是设计者要求提出和确认的。

    1)    产品的用途是什么?系统的功能是什么?

    2)    用户想要如何同系统打交道?

    3)    系统的重量和体积有哪些要求?

    4)    系统需要连接哪些外设?

    5)    系统处理哪些类型的数据?

    6)    系统在什么样的环境下运行?

    7)    所要求的内存和辅助存储器多大?

    8)    用户是否需要自己更新操作系统和应用程序?

     

    如果我们没有尽量分析分析出客户潜在的需求并且得到客户的确认,而客户在研发过程当中再提出来,这就会影响了我们的项目开发的进度,下面是我在上家公司研发GPS产品的时候遇到的问题:

    1)   客户要求在产品中添加camera功能。

    2)   客户要求可以自己更新操作系统

    初步研发好样机之后,寄给美国、以色列和俄罗斯客户,它们测试之后发现了一些问题,然后我们修正了这些bug之后,需要更新上的系统,可是没有多余的样机了,而且目前产品只能通过USB来更新,而客户那边都没有这些更新的工具。在时间和成本上也不允许客户把样机寄回来更新之后再寄回去,只能把开发工具和操作系统的镜像寄给客户,而且还要写一份详细更新文档。这样客户才能更新,后来改为从SD卡来更新操作系统才解决了这个问题。

     

    2.2确定项目的约束条件

    约束条件属于项目开发过程中的不利因素,指的是项目开发过程中限制项目能否按时完成的内部和外部原因,在项目进行实际开发之前,要把约束条件找出来并且要提出解决的办法,否则很有可能会给项目带来在有效的时间内无法解决的问题。一般的约束条件有下面一些:

     

    1)  是否要满足项目的阶段性或者完工的工期限制?

    2)  项目的预算是否限制在一个固定的预算内?

    3)  分派到该项目的最大人数是多少?

    4)  员工的技术知识和经验是否足够?

    5)  该项目是否依赖于某些供应商?

    用户需求分析 User Requirement Analysis   

    在系统设计之前和设计、开发过程中对用户需求所作的调查与分析,是系统设计、系统完善和系统维护的依据.

     

    3.  体系结构设计

    此阶段是通过需求分析的结果来设计出满足用户需求的嵌入式系统产品,描述系统的功能如何实现是体系结构设计的目的,体系结构是系统整个结构的一个计划,而后用于设计并搭建整个体系结构的构件,其中系统的体系结构取决于下面的因素:

     

    1)   系统是硬实时系统还是软实时系统

    在硬实时系统的情况下,对实时的要求非常严格(如某些工业实时控制),因此,需要详细和严格地进行实时性分析。在软实时系统的情况下(如PDA等),对实时性的要求没那么严格,偶尔超时不会对系统性能造成不利的影响。

     

    2)   是否需要操作系统

    如果产品只需要非常简单的I/O操作,仅有一项或很少的事务需要处理,那么操作系统可能就不是必需的,而可以通过在裸机上编写或采用一个很小的内核来创建必要的服务。否则,最好是使用一个嵌入式操作系统来加快开发的进度。

     

    3)   产品的成本、尺寸和功耗的要求

    这些要求决定了我们需要下硬件/软件协同设计的过程中,需要确定哪些功能用硬件实现或是用软件实现,哪种方式是更好的选择。一般的原则是,如果嵌入式系统中使用的算法和计算很可能改变,软件实现是理想的选择。用硬件实现需要更多的空间、更高的成本和更大的耗电量,通常硬件的成本一般高于用软件实现的成本。但是,软件实现会降低执行速度,并且要求更高容量的存储器和更高速度的处理器,这样成本也可能更高。对于那些需要在严格时间限制内完成的密集执行的任务,必须用硬件来实现;可编程的算法可以用软件来实现,特别是需要灵活性和将来改进的算法。所以需要硬件和软件人员一起来讨论如何采用哪种方式来解决这些问题。

     

    4)   选择处理器

    如果是小型的应用,选择微控制器就可以了;否则就需要选择微处理器;但如果需要那个进行信号处理,就需要选择DSP,当然对于多功能系统中,一个嵌入式系统可以包含一个微控制器、微处理器和一个DSP,以满足不同的功能需求。

     

     

    比如对于A项目来说,根据客户的需求,我们需要选择微处理器来进行处理和控制,同时此系统并没有要求硬实时系统,但因为需要良好的人机界面,所以需要选择操作系统,这样就可以设计出下面的体系结构。

    图3 嵌入式系统体系结构体

    4. 硬件/软件协同设计

    嵌入式系统的核心处理器,所以嵌入式系统开发一般是先根据客户对产品的功能需求先来选出处理器。在选择元器件的时候都需要考虑下面一些因素:

     

    1)   成本

    包括元器件本身成本和外围电路的成本。比如对于LCD显示屏来说,有些LCD显示屏的驱动电路是设计中LCD显示屏的连接线上的,而有些就没有。

     

    2)   工作和存储温度

    这个需要根据客户的要求来选择了,对于工作温度,一般情况是民用温度范围是0°C~70°C,工业级用的温度范围是-45°C~85°C,军用级的温度范围是-55°

    C~125°C。

     

    3)   功耗

    元器件的都有对功耗指标的描述,特别要考虑的是RAM存储器、LCD显示屏和处理器的功耗,尤其是前两者,当然了,如果系统中可能还有有其他功耗很多的元器件,这和系统的应用场合有关。

     

    4)    采购周期

    这个要看要开发的产品对采购周期的依赖程度,而且采购民用级和工业级的周期也不一样,另外还要考虑生产厂家对元器件的持续生产情况。

     

    5)    电磁兼容性指标

    电磁兼容性(EMC)是指设备或系统在其电磁环境中符合要求运行并不对其环境中任何设备产生无法忍受的电磁干扰的能力。因此,EMC包括两个方面的要求:一方面是指设备在正常运行过程中对所在环境产生的电磁干扰不能超过一定的限值;另一方面是指器具对所在环境中存在的电磁干扰具有一定程度的抗扰度,即电磁敏感性。

     

    4.1 选择开发平台

    4.1.1选择处理器

    对于大多数嵌入式系统的开发者来说,往往更愿意选择自己熟悉的处理器,以节省熟悉新的处理器的时间,但是这并不一定是一种好的方案,理想的方案应该是根据用户的需求和项目的要求来选择处理器,在选择处理器是要重点考虑下面几个方面:

     

    1)   功能

    比如处理器是否集成了所需要的功能,比如,我们开发游戏机,那么就要选择集成了3D图形加速器的处理器,这样不仅可以简化了软件的开发难度,也可以充分利用3D图形硬件加速器的来处理3D图像的显示;如果我们的产品需要多个UART来同时和外围设备通信,这就要考虑所选择的处理器是否集成了足够的UART。

     

    2)   处理速度

    处理速度和CPU的内部时钟有很大的关系,这个时钟就是外部时钟(一般是晶体振荡器)经过PLL倍频后产生的,

    图4 S3C6410产生系统时钟框图

    我们知道处理器执行一条指令一般经过取指、译码和执行这三个步骤,而这个过程是需要CPU的内部时钟来同步的,所以处理器的处理速度就取决于CPU的内部时钟和指令的复杂程度。这里要注意的一个问题就是并非主频越高的处理器的处理速度就越快,这还要看它采用的是RISC(Reduced Instruction Set Computer,精简指令集计算)还是CISC(复杂指令集计算)指令集有关,只能说同一系列的处理器,主频越高,处理速度越快。

     

    我们先来了解CPI的概念:CPI(Cycles Per Instruction,每天指令周期数),也即执行一条指令所需要的周期数。在RISC芯片中,应尽量减少CPI的值来提高处理器的运算速度。

     

    一个程序总的CPI=∑(每条指令的CPI×指令的使用频率)

     

    在此假设这个程序用到A、B、C和D这几条指令,而A指令执行了2次,B指令执行了3次,C指令执行了4次,D指令执行了一次,其中执行A、B、C和D这几条指令所需要的是总能周期数分别为2、1、1和2个时钟周期,那么这个程序中的CPI=(2×2/10)+ (1×3/10)+ (1×4/10)+ (2×1/10)=1.7个时钟周期,那么可以利用下面的公式:

    CPU执行时间=此程序中的指令数量×此程序用的指令数总的CPI×时钟周期

    可以算出CPU执行这个程序的时间=4×1.7×时钟周期,这里的4是指A、B、C和D这四条指令,时钟周期是CPU内部时钟。

     

    MIPS(Million Instruction Per Second),每秒百万次指令,它=CPU执行时间的倒数。

     

    4.1.2选择外围设备

    这里主要描述主要元器件的选型,其中存储器的选择均需要考虑下面的一些指标:

    ⑴速度

    存储器的速度是用存储器访问时间来衡量的,访问时间是指存储器接收到稳定的地址输入到完成操作的时间,例如,在读出的时候,存储器往往数据总线上输出数据就是操作结束的标志。访问时间的长短主要与制造器件的工艺有关。

    图5 NAND FLASH读数据的时序图

     

    4.1.2.1    RAM存储器选择

    RAM存储器分为SRAM和DRAM,其中SRAM只要是芯片有电就会保留其中的内容,但如果切断了电源或者暂时断电了,其中的内容就会永久性丢失;而DRAM只有极短的数据寿命,通常不超过0.25s,即使是在连续供电的情况下也是如此,所以为了不让保存在DRAM中的数据丢失,就需要DRAM控制器对DRAM进行周期性刷新。

     

    SRAM和DRAM的特点比较如下:

    ⑴SRAM比DRAM速度快,因为DRAM需要周期性的刷新。

    ⑵DRAM的存储密度大于SRAM,因为SRAM的电路基本单元时晶体管,而DRAM的电路基本单元时电容。

    ⑶DRAM需要周期性刷新,所以需要专用的DRAM控制器。

     

    选择RAM时需要考虑下面一些因素:

    1)    如果系统的随机存储器的容量不是很大,一般采用SRAM;反之,选择DRAM存储器。

    2)    如果选择微处理器,而微处理器集成了DRAM控制器,这时选择DRAM比较好。

    3)    如果嵌入式系统对功耗要求比较严格,可使用SRAM,因为DRAM需要周期刷新,所以功耗更大。

    4)    位宽,也即每个传输周期传送的数据量(比如16bit)。

     

    图6 DDR SDRAM的技术参数

    4.1.2.2    FLASH存储器选择

    FLASH存储器一般分为NOR FLASH和NAND FLASH,NOR FLASH的特点是可以随机读取任意单元的内容,适合程序代码的并行读写存储;NAND FLASH可以按顺序存储单元的内容,适合于数据或文件的串行读写存储。

     

    目前NOR FLASH存储器的价格比较贵,而NAND FLASH存储器的价格相对来说比较合适,所以现在采用微处理器作为处理器的嵌入式系统中比较流行的启动方式是采用NAND FLASH的启动方式,也即把启动程序和系统的镜像写到NAND FLASH中,开机之后从NAND FLASH中启动。

     

    选择NAND FLASH时主要需要供电电压、访问时间和页编程及块擦除时间。

    图7 NAND FLASH一些技术参数

    4.1.2.3    LCD显示屏选择

    LCD显示屏选择需要考虑下面一些指标:

    1)    分辨率及尺寸

    2)    是否强光下可见。

    3)    RGB数据接口

    图8 LCD屏的功耗参数

    4.1.3选择嵌入式操作系统

     

    选择嵌入式操作系统需要考虑下面一些因素

    1)    系统的实时要求,如果要求是硬实时的系统,那么应该选择VxWorks操作系统较为合适

    2)    如果是软实时系统,而且不需要特别复杂和友好的人机界面,那么应该选择linux操作系统,否则,选择WINCE操作系统可能较好,当然,如果要开发智能手机,那么Android是比较合适的选择。

    3)    操作系统的移植难度

    4)    项目开发人员是否熟悉此操作系统

    5)    系统要求的RAM内存大小

     

    比如,如果要求嵌入式系统要求支持512MB及以上这的RAM内存,那么就不能选择WINCE操作系统了,而linux和android是可以支持的。

     

    4.1.4选择开发板或者是评估板

     

    为了加快嵌入式系统的开发,一般需要选择和我们要开发的产品功能相近的开发板,这样可以通过评估开发板的功能和性能来对我们要开发的产品有个初步的预估,而且可以先在开发板上定制系统、开发bootloader、驱动和应用程序,这样就让软件开发的工作尽可能可以和硬件同时进行。

     

    4.1.5 编程语言的选择

    选择编程语言需要考虑下面的一些因素:

    1)    软件开发人员最熟悉的是哪种语言

    使用最熟悉的语言可以开发出性能更好程序,而且较少一些bug。

     

    2)    语言使用的广泛程度

    嵌入式系统开发的系统和驱动层的开发,基本上是用汇编、C和C++,而对于应用层的开发主要是用C++、Java或者是C#,其中C++基本上是开发应用程序的通用语言,java主要用在android操作系统的应用层开发,C#主要用在WINCE和MB操作系统的应用开发中。

     

    3)    语言的性能如何

    一般来说,越是高级的语言,其编译器和运行库附件的开销越大,应用程序也就越大,那么运行速度会越慢。例如汇编语言编写程序的性能>C>C++>C#,其中C#和java需要包含额外的组件---解释器,以允许“在运行过程中”处理代码,至于C#和java哪个性能较好,应该看应用场合了。

     

    4.2 硬件设计

    4.2.1原理图设计

    这一阶段的设计需要硬件开发人员熟悉处理器的功能和各个引脚的用途,下面我把之前在原理图设计阶段遇到的问题做个总结:

    1)    SDRAM bank address引脚连接出错

    根据客户的要求,我们要把产品64MB的SDRAM升级为128MB的SDRAM,可是在原理图设计的时候,把用于Bank选择的地址端画错了,就直接导致无法有效利用128MB的SDRAM,而只能使用其中的64MB,那么就只能改变来解决这个问题了

    图9 S3C2440 SDRAM地址引脚连接示例

    图10 S3C2440和SDRAM芯片的连接图

    2)    USB HOST端供电电压不足

    连接到USB HOST端的USB设备(比如U盘、USB鼠标)需要5V的供电电压才能正常工作,可是在设计的时候直接由电池输出来的电压(最大只有4.2V,这是我们选择的电池决定的)来给USB HOST端供电,这样就导致了在用电池供电的时候,USB鼠标和U盘不能工作。后来添加了一个升压IC之后才解决了这个问题。

     

    3)    CPU的LCD显示数据接口和LCD显示器的数据接口的次序没有对应

    这个问题就直接导致了显示颜色不正常,偏色等情况。

     

    4)      设计原理图的时候,需要考虑软件的实现方式,比如串口是否需要流控的方式。

     

    4.2.2 PCB设计

    这里我特别提一下SDRAM走线的问题,之前一个产品的第一板回来之后调试ok后,我们的驱动在这一版本调试完成之后也做了备份,后来经过调试之后需要做第二板,用我们之前验证ok的系统来在第二板上跑的时候,系统无法正常加载,总是停在一个固定的地方,经过检查这两个版本的原理图,其中修改的地方不可能让系统跑不起来的,经过各种修改无效之后,想到对CPU降频处理,由533MHZ降到400MHZ,这样系统就可以跑起来了,后来经过验证时SDRAM的走线引起了这个问题。

     

    4.2.3 硬件的装配和测试

    主要是样板的焊接、各模块电压电流测试和检查模块出来的波形是否正常。

     

    4.2  结构设计

    4.3  软件设计

    4.3.1 系统和驱动开发

    如果购买了开发板或者评估版,系统和驱动的开发就可以把一些尽量可以完成的工作在开发板上来完成,而不需要等到样机回来再调试,这样可以缩短开发时间。

     

    4.3.1.1 建立交叉开发环境

    因为嵌入式系统的资源受限制,无法建立起所需要的开发环境,并且对于只面对产品的嵌入式系统来说,没有必要设计成既是运行环境又是开发环境的系统。那么就需要在PC机上建立开发环境来开发出那些在嵌入式系统中运行的程序。

     

    对于要开发基于WINCE6.0操作系统的嵌入式系统,那么就需要在PC端安装VS2005+PB6.0,以及一些附件,这样就可以在PC端来开发出可以在嵌入式系统中运行的程序了。

     

    4.3.1.2 定制系统

    这需要根据应用来定制,对于WINCE操作系统来说,微软开发的VS2005+PB6.0这个IDE便于我们来定制系统

    图11 WINCE6.0的PB6.0系统定制图

    这样很便于我们根据客户的需求来定制系统,但是这需要我们熟悉操作系统的各个模块的功能,而且还要注意他们之间的依赖关系,只有对操作系统所有的模块都很熟悉,才能很快定制出所需要的操作系统,这是需要很长时间去熟悉的,尤其是linux操作系统。

     

    4.3.1.3 开发bootloader

    Bootloader的作用是初始化硬件并且引导操作系统,还有一个更为重要的功能就是把操作系统镜像文件写到FLASH中,这是我们在开发及调试过程中需要经常性的动作。

    图12  bootloader引导系统启动的流程图

     

    开发bootloader的主要内容如下:

    1)    选择更新系统的方式

    在开发过程中,我们一般通过USB、网口或者是SD卡的下载方式来把操作系统写到FLASH中,当然了,bootloader也以把自身的镜像文件写到FLASH中。

    2)    在bootloader中添加产品logo的显示

    3)    在bootloader中进行充电的指示

    4)    在bootloader中进行一些参数的设置,操作系统会采用这些参数来做相应的动作。

     

    4.3.1.4 开发驱动程序

    当bootloader能够正常下载操作系统镜像文件之后,就可以在板子上进行驱动的调试了。一般情况下,CPU都集成了不同的控制器来控制对应的外围设备,比如DRAM控制器用于控制DRAM存储器,LCD控制器用于控制LCD显示屏的正常显示。下面以开发显示驱动为例来描述驱动开发主要包含的内容:

    1)    先熟悉CPU中对应的控制器部分。

    2)    掌握要驱动的外围设备的工作原理。

    3)    根据外围设备的工作原理来配置相应的控制器部分。

    4)    编译生成新的操作系统镜像文件通过bootloader写到flash后看能否正常工作,如果可以,就表示此驱动的调试基本完成了,否则就要分析问题和解决问题了。

     

    根据外围设备的特点,开发的驱动一般分为三种:

    1)    根据外围设备的时序要求,需要配置微处理器的寄存器来产生外围设备需要的时序来驱动外围设备正常工作。

    这里典型的设备就是LCD显示屏,比如我们需要根据下面的时序图来配置微处理器的寄存器,只有正确配置了寄存器,才能正常驱动LCD屏的正常显示

    图13 LCD显示屏时序参数

    这种类型的设备还有camera、VGA等。

    2)    外围设备需要正常的上电和断电要求

    图14 SIM5218的启动和关闭的电源要求

    3)    需要正常的物理连接和上电,对上电时序没有要求

    图15 SR-96的电路设计图

     

    4.3.2 应用程序开发

    应用程序开发部分即使没有开发板,也可以在模拟器中先进行调试,比如WINCE操作系统就提供WINCE模拟器来为应用程序开发人员提供开发环境,这样,应用程序开发部分也可以和硬件设计阶段并行开发。

     

    在应用程序开发阶段,驱动开发人员需要协助进行应用开发,应用程序开发的内容主要如下:

     

    1)    验证定制的操作系统是否满足客户的需要,比如对于WINCE操作系统来说,是否添加了对透明效果处理的支持,这部分可以在开发板中验证。

    2)    在开发板中根据驱动开发人员提供的接口来完成和驱动的正常通信。

     

     

    5. 系统调试和集成

    5.1 系统的调试

     

    这阶段的工作是整个开发过程中最复杂、最费时的,特别需要相应的辅助工具支持。

    主要的工作包含两方面:

    1)    硬件工程师和驱动工程师协同调试

    当样机的焊接和硬件测试完成之后,就要把正对样机移植好的操作系统下载到样机中进行调试,这时就需要硬件和驱动工程师一起调试了。先是驱动工程师通过编写驱动程序来驱动外围设备,如果不能正常驱动外围设备,就要对自己的驱动的设计进行检查,如果多次检查没有问题的情况下还是不能正确驱动外围设备,那么就要和硬件工程师沟通,说明情况,一起来解决问题。

    2)    驱动工程师和应用工程师协同调试

    在第1)部分中确认把系统所需要的功能调试完成之后,也就是驱动程序可以正常驱动外设设备之后,这时候就要把应用程序加进来一起调试,主要看应用程序是否正常调用驱动程序提供的接口来正常工作。

     

    这里总结一下之前调试过程中遇到的一些问题和总结:

    1)    SDRAM的时序要求的问题

    为了降低成本,产品由之前128MB的SDRAM换为另一种128MB的SDRAM,仔细比较这两种SDRAM的数据手册,发现几乎没有差别,可就是无法更新系统,经过多次对RAM控制器的寄存器的配置后,对CL的值由2clocks改为3clocks后,就正常工作了

    图16 S3C2440的RAM控制器CL参数

    这里是结合SDRAM中对此参数的要求来决定的

    图17 SDRAM的CL参数

    2)    SDRAM的供电电压问题

    在通过串口下载nboot的镜像文件到SDRAM并且校验的时候,校验出错,经过验证之后发现软件没有问题,只能尝试从硬件查找了,发现对SDRAM的供电不是很稳定导致的。

     

    3)    适当的备份

    在一次测试中,发现本来已经ok的功能突然不正常工作了,因为这一阶段自己做了好些修改,一时找不出问题所在,后来就怀疑是硬件的问题,经过硬件同事的对硬件的测试之后,发现硬件是ok的。这时候要判断导致此问题的办法,最好是用之前ok的软件版本来在此板子上测试,如果是ok的,那就说明是软件的问题;如果不行就说明是硬件的问题。所以这时候,之前对代码的备份就体现出其重要性了。这有助于我们对问题的定位。

    4)    硬件上的变动,就算是很小的变动,也尽量要和驱动工程师沟通和确认。

    5.2系统的集成

    将测试完成的软件系统装入制作好的硬件系统中,进行系统综合测试,验证系统功能是否能够正确无误地实现,最后将正确的软件固化在目标硬件中。主要的测试包括可靠性测试、性能测试、安全性测试、环境测试和电磁兼容测试。

     

    6. 系统测试

    6.1 测试的原因

     

    1)    找出错误

    测试是为了找出系统中存在的bug,包括硬件和软件的。

    2)    减少风险

    测试可以将自己、公司和客户的风险降到最低,测试的目标就是证明系统与软件正如设计所要求的那样正常工作。要确保产品的功能和性能可以满足可以的需求,测试人员会尽力测试系统与软件,尽可能找出任何一个可能的bug。

     

    3)    降低成本

    Bug发现的越早,修改的费用就越低。

    4)    提高性能

    找到bug并且解决了bug,能优化系统性能,而且还有可能避免致命的错误。

     

    6.2 何时测试

    在嵌入式系统进入开发的时候就可以了,比如,我们一般会在开发板上先测试系统的性能。测试包含硬件测试、软件测试,而且实际上软件过程中的调试也属于测试的范畴,这就是由开发人员进行的模块测试和调试。当然了,这部分的测试时不完整的,所以需要测试人员进行全面的测试。

     

    6.3测试的内容

    6.3.1功能测试

    功能测试也称为黑盒测试,这是因为其测试实例在设计时不引用被测试程序的实际代码部,也就是不用暴露盒子的内部,黑盒测试一般包含下面几点:

    1)    边界测试

    2)    异常测试

    3)    错误猜测

    4)    性能测试

     

    6.3.2 覆盖测试

     

    功能测试的弱点在于它很少能检查完所有的代码,而覆盖测试则尽可能使每条代码语句、判断点或是判定路径都最少被执行一次,从而避免功能测试的弱点。覆盖测试也称为白盒测试,它需要运用软件实现的全部知识来进行设计,测试时需要看到程序实现、执行的细节,白盒测试一般包含下面几点:

    1)    语句测试:选择的测试实例至少执行一次程序中的每条语句。

    2)    判断或分支覆盖:选择的测试实例使每个分支至少运行一次。

    3)    条件覆盖:选择的测试实例使每个用于判断的条件的条件具有所有可能的逻辑值。

     

     

     

    展开全文
  • 动力电池管理系统(BMS)策略与开发方法

    万次阅读 多人点赞 2019-03-19 18:58:18
    那么对于新能源汽车BMS如此重要,今天漫谈君就和大家聊一聊动力电池管理系统(BMS)策略与开发方法。 动力电池需要从”电量管理“、”充放电“、”能量回收“等等各个方面来管理。那么对于新能源汽车BMS如此重要,...
  • 信息系统开发的发展过程经历过所谓“自底向上”方式和“自顶向下”方式,从整体上分析和总结了两种方法的优缺点。  自底向上方法的优点有:  有助于发现和理解每个系统的附加需要,并易于判断其费用  相对...
  • 数据字典模块主要对平台所需数据字典(即选项数据)进行管理,整个数据字典数据为平台所共享,操作员可灵活控制整个平台中的可选数据(主要为下拉框中的列表数据)。提高数据的重复利用率,加速新项目开发的效率。
  • GIS 系统开发

    万次阅读 2012-06-03 17:35:59
    最近在做一个煤矿的三维项目,其中矿区... 现在的实现技术并没有采用gis技术,而是用virtools+vc模拟实现了类似gis的功能,但是巷道图以及关键的设备显示并准确,避灾路线也没办法动态生成。自己琢磨过gis技术后,总
  • 信息系统分析与设计课程心得

    万次阅读 2017-02-28 13:41:39
    信息系统分析与设计课程心得此博客为信息系统分析与设计课程的学习心得记录。一、绪论1概念1.1信息要了解信息系统,首先要了解信息的概念。信息是我们理解世界的重要概念,我对它的定义是:信息是对客观事物及其相互...
  • 嵌入式系统开发设计---嵌入式系统开发设计

    万次阅读 多人点赞 2018-09-20 07:42:01
    嵌入式系统设计的主要任务是定义系统的功能、决定系统的架构,并将功能映射到系统实现... 嵌入式系统的设计方法跟一般的硬件设计、软件开发方法不同,是采用硬件和软件协同设计的方法开发过程不仅涉及软件领域...
  • 本人参加的是2017年上半年信息系统项目管理师考试,今天看到2017上半年考试的成绩合格分数为45,也算是侥幸通过,在这里写一写自己是如何备考的,供各位考友参考一下。 这里说的50天是指白天上班以业余时间备考所需...
  • 开源的运维系统不少,比如nagios、zabbix、cati等等,但是遇到自己个性化的运维需求的时候,总是显的力不从心!最近在学习python,所以就考虑用python+django+twisted来定做一个完全个性化的运维系统。 运维系统有几...
  • MIS系统开发教程

    千次阅读 2014-02-22 11:51:13
    MIS系统开发教程 第一部分 MIS系统开发理论 构成企业管理信息系统的5个基本要素 构成企业信息系统主要包括5个基本要素:企业的组织结构、流程、数据、商务规则与功能(性能)。其中从用户的角度主要关注...
  • 本项目本着避免重复造轮子的原则,建立一套快速开发JavaWEB项目(springboot-mini),能满足大部分后台管理系统基础开发功能,使得开发人员直接可从业务模块开始,减少大量的重复开发工作。前端框架使用 layui-mini...
  • 零基础入门微信小程序开发

    万次阅读 多人点赞 2018-07-03 02:45:07
    本课程是一个系列入门教程,目标是从 0 开始带领读者上手实战,课程以微信小程序的核心概念作为主线,介绍配置文件、页面样式文件、JavaScript 的基本知识并以指南针为例对基本知识进行扩展,另外加上开发工具的安装...
  • 信息系统项目管理--上午分析笔记

    万次阅读 2019-10-29 10:22:29
    信息系统项目管理–上午分析 软件度量:项目度量、产品度量、过程度量 RBAC基于角色的访问控制,用户只能被动接受,能自主决定,也能自主的将访问权限授予其他用户。 运维管理平台使运维自动化、操作化,但并...
  • [全程建模]软件开发方法论综述

    千次阅读 2010-03-02 09:41:00
    本文选择《软件工程指全程建模实现》第二版书稿内容,因为这段文字中部分内容来源于网络并经过本人整理,... 软件开发方法论60年代中期开始爆发了众所周知的软件危机。为了克服这一危机,在1968、1969年连续召开的两
  • 软件开发方法论概述

    千次阅读 2010-12-19 13:51:00
    软件开发方法论概述在60年代的软件开发行业,随着所开发的软件复杂度不断提升,使用原先的方法(1)开发出来的软件终于能满足需要,其所出现的问题是层出不穷,而且由于缺少必要的文档,人们又没办法寻找定位出其中...
  • 2009年上半年 信息系统项目管理师 上午试卷 (考试时间 9 : 00~11 : 30 共 150 分钟) 1. 在答题卡的指定位置上正确写入你的姓名和准考证号,并用正规 2B 铅笔在你写入的准考证号下填涂准考证号。 2. 本试卷的...
  • 2011年上半年 信息系统项目管理师 上午试卷 (考试时间 9 : 00~11 : 30 共 150 分钟) 1. 在答题卡的指定位置上正确写入你的姓名和准考证号,并用正规 2B 铅笔在你写入的准考证号下填涂准考证号。 2. 本试卷的...
  • 面向对象的开发方法

    千次阅读 2015-06-17 11:54:33
    面向对象的开发方法(Object Oriented,OO)  从事软件开发的工程师们常常有这样的体会:在软件开发过程中,使用者会不断地提出各种更改要求,即使在软件投入使用后,也常常需要对其做出修改,在用结构化开发的程序...
  • java web开发(二) 接口开发

    万次阅读 多人点赞 2016-06-03 16:50:34
    java web开发(一) 环境搭建讲解了如何搭建一个Java Web项目,... 假设要做一个简单的学生信息管理系统,数据库名为students_manage,并且先设计一张学生表,表名为student。 1.打开Sqlyong工具,如果还没创建连接...
  • 设计方法(原型法、敏捷开发

    千次阅读 2017-03-13 15:18:58
    定义:又称快速原型法,不属于敏捷开发。 根据需求用IDE实现基本功能,然后用户试用、补充和修改的重复过程,最后的版本再决定是demo还是正式版本。 分类 1. 抛弃型原型 - 此类原型在系统真正实现以后就抛弃不用了...
  • 基于人工智能的智能化地理信息系统

    万次阅读 多人点赞 2017-11-05 09:34:53
    基于人工智能的智能化地理信息系统   摘要:地理信息系统在飞速发展的同时,对现实世界的地理问题的空间分析能力的相对不足,成为了遏制其发展的一个重要原因之一。而近年来,人工智能领域取得的重大研究成果,...
  • ●在计算机系统中,(3)是指在CPU执行程序的过程中,由于发生了某个事件,需要CPU暂时中止正在执行的程序,转去处理该事件,之后又回到被中止的程序。 (3)A.调用 B.调度 C.同步 D.中断 ●掉电后存储在(4)中...
  • 提高软件开发效率的方法

    千次阅读 2019-01-12 21:28:23
    一个开发任务下达以后,我们希望尽快的实现的,对软件开发工程师的要求是:多快好省 多--单位时间产量高 快--同样的产量所需的时间少 好--质量高 省--省钱,省时,省资源 这四个目标中最主要的又是“快”,也...
  • 地理信息系统GIS的评价

    千次阅读 2009-06-10 13:26:00
    地理信息系统的评价 系统评价是指对一个GIS系统从系统性能和经济效益两方面进行评价。新系统的全面评价一般应在新系统稳定运行一段时间后才进行,以达公正、客观。系统评价的结果是写出评价报告和改进效益措施的实施...
  • 虽然系统开发的实践已经超过半个世纪了,在各个方面都取得了长足的进步,解决了很多难题,但我们在开发效率方面的提高明显跟上系统规模的膨胀。虽然各种新想法,新方案虽然层出不穷,但始终都没成为大家
  • 鸿蒙系统开发app入门系列-- 第一个demo

    万次阅读 多人点赞 2020-09-12 16:28:01
    当脉脉上全是dis鸿蒙系统的时候,我已经做完了第一个demo app,毛主席说过没有调查就没有发言权,与其坐而论道不如行而起之,来通过第一个app,感受一下鸿蒙app的开发和普通ios和Android开发有什么不同. 先自我介绍一下...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 410,278
精华内容 164,111
关键字:

不属于信息系统开发方法的是