TI-RSLK 模块 4 - 讲座视频 - C 语言编程

展开字幕 关闭字幕 时长:26分30秒
评论 收藏 分享 上传者:hi5
大家好, 我是 John Valvano。 在本模块中,我们将讨论软件设计。 我们首先介绍一下模块化设计这个概念。 模块是什么,它是系统的一个子集, 它同时包含软件硬件,而且具有完整的任务。 所以我们会将它视为一个完整的任务。 当我们把这些模块放在一起时, 我们可以从不同的角度来看待它们。 其中一个角度叫做调用图。 这意味着,如果SwitchMain 中的软件 可以调用针对不同模块的 switch 中的函数, 我们将会绘制这样一个调用图箭头。 这个箭头表示,这将是高级别, 这将是低级别。 类似地,如果SwitchMain 中的软件 可以调用 LaunchPad 中的软件,我们将会 绘制一个调用图箭头,来表示 高级别函数与低级别函数之间的 因果关系--层次结构关系。 而且,我们会将与一个事件相关的 所有任务-- 例如,与开关相关的所有函数, 以及与 LaunchPad相关的所有函数-- 封装在独立的模块中。 我们将要解决的问题 并不复杂,我们将在一个输入上 配备一个开关。 如果按下开关, 则会将发光二极管切换到另外一种 状态。 另一种在互连情况下看待这些模块的方法 称为数据流图。 数据流图显示了连接情况。 这是一个硬件模块。 这里的所有其他模块都是软件模块。 关于开关是否关闭的布尔信息 被编码在数据流图的箭头中。 所以,数据是向这个方向流动的。 即使是 SwitchMain调用 switch, 数据实际上也是在向另一个方向流动。 而在这里,数据则是从 main 向 LaunchPad 流动, 因为我想要开关 LED 然后,在物理层面上,我在数据流图中包含了 可以发光的 LED 而且,通过这个数据流图, 我们可以定义模块化意味着什么。 系统的模块化,如果您愿意, 这也是系统的精华所在-- 是多个模块的函数。 因此,我们希望最大限度地增加模块数量, 同时尽量减少它们之间的互连。 特别是,我们可以查看带宽之类的 东西,它是每秒跨屏障传输的 字节数。 因此,我们希望最大限度地增加模块数量, 同时尽量减少它们之间的互连。 针对互联的一个简单的定量测量方式是, 测量每秒从一个模块流到另一个模块的 字节数。 这便是我们将会在这里采用的理念。 那么,让我们开始吧。 当我们讨论如何制造一些复杂的东西-- 换句话说,模块化系统 整体思路就是能够提高复杂性。 可让我们做到这一点的一种方法是使用多个线程。 线程是由正在执行的软件引起的操作。 所以,引发线程的是软件的行为。 我们将会得到一个多线程环境, 其中有一个主程序。 而且,我们将会有多个中断。 例如,我可能会有硬件触发的中断。 当我触摸开关时,将会触发一个中断。 我们将会在多个模块中介绍这种中断的 实际工作方式。 但是在这里,我们只需要了解一点就足够了, 那就是,当您触摸开关时,系统 运行与这个触摸操作相关的软件 然后,如果我们想要周期性地执行 某个操作,我们将需要另外一种中断。 我们将会使用一个频率为,比如说 100 赫兹的计时器中断。 而且,我们将从这个层面上执行软件 我在这里绘制一个主程序。 然后绘制初始化。 然后,我们在这里绘制一些东西。 然后就有了一个循环。 我们之所以将其称为线程, 是因为我们可以将正在执行的软件想象成 一条单一的轨迹。 即使这是一个函数-- 即使这个初始化是一个函数, 我们仍然可以绘制一条-- 我们可以 一笔画出一条代表其执行顺序的直线。 这便是我们将其称为线程的原因。 一系列指令,由这些指令 引起的操作,这便是线程。 但是中断是特殊的。 中断是硬件触发的软件 操作。 在这里,我们将打断这个线程, 从这里开始,因为我们触摸了开关, 执行该软件,然后再次打断该线程, 然后重新返回这里。 所以线程是由正在执行的软件引起的 操作。 在本课程中,我们将使用一个 单一的前台线程、一个主程序,以及多个 在特定事件时执行的中断线程。 这是增加系统复杂性的一种方法。 您要做的最困难的事情之一是, 确定从哪里开始。 我要告诉您一个很不幸的消息。 您可能也在其他地方听到过这个 说法-- 需要花费 1 万小时的时间, 才能熟练掌握一个技能。 我并不是要打击您。 如果您坐在电脑前, 编写尽可能优秀的代码,在大约一个小时的时间里, 您可能能够写出 100 行代码 如果您将这两个数字相乘, 达到一百万行代码的分界线后, 您将会成为一名优秀的软件设计师。 说这些也不是为了打击您。 我的意思是,行动起来。 说这些是为了鼓励您马上加入进来并编写许多 许多的代码 这张幻灯片讨论的是,在开始写代码之前, 如何完成软件构想。 这涉及到了状态这个概念。 我将状态定义为:您知道什么? 如果您有一个系统,您可能知道什么? 或者有时候是,您认为自己知道什么, 或者您认为什么是真实的,这便是状态。 例如,我可能在这条路上有一个机器人。 我的机器人在这里。 我觉得它在沿着这条路移动的过程中离右侧 墙壁太近了。 离右侧墙壁太近-- 这便是我认为真实的事情。 您现在要做的是 考虑这个问题, 并写下您的系统可能处于的 所有状态。 我在一个小圈子里。 我处于停滞状态。 我撞到墙上了。 我走错方向了。 我赢了比赛。 我到达了终点。 所以,我将会考虑所有的状态。 有些状态是相互排斥的, 有些则不是。 例如,您可能会有一个绿色 LED 闪烁的状态。 这个状态可能会与机器人离墙太近的状态并存。 所以,状态之间不一定是相互排斥的。 但是,您需要将它们都写下来, 考虑哪些事情是您的系统需要知道或 认为是真实的。 这样做后,您可以问自己以下几个问题。 我们从哪里开始? 初始状态是什么? 或者是下面的这个也比较简单的问题-- 我需要知道什么? 我要得到什么信息,才能认为 我离墙壁太近? 在这种情况下,我可以写下所有的传感器-- 输入传感器 然后它不单单是一个数据收集器, 更是一个嵌入式系统 所以它有输出。 我该怎么做? 我会采取哪些操作? 我想移动。 我想转弯。 我想停下来-- 诸如此类。 我将会使用哪些操作,为了执行 这些操作,我需要生成什么输出? 我们将会看到,我们有两个电机 我们将必须单独驱动每个电机 然后更难的是,如何从一个状态转变到另一个 状态? 换句话说,如果我离右侧墙壁太近, 我想要移到中间位置,我怎样才能从一个不佳的位置 移动到理想位置? 然后,很明显,我们想知道, 我们如何在完成后获知已经完成? 所以,这种状态本质上是一种 在实际坐下来开始写代码前, 构想您的软件硬件系统的方法。 另一种思考问题的方法是 将其分解成模块。 下面我们将介绍这种方法。 用于讨论将系统分解成 模块化部分的术语共有三个。 它们具有大致相同的含义。 逐次求精、逐步求精 系统分解--在这个背景下, 它们都指的是相同的事情。 那就是,我们将会从任务开始。 让我们进行赛跑。 我想要在跑道上尽可能快地奔跑。 但这太复杂了,我不知道究竟该怎么办。 因此,求精的整体思路就是将其分解成 多个片段。 比如,我可能想要移动。 我可能想要进行感测。 我可能想要进行思考。 然后对于上面的每个任务,我想要 将其分解为更小的部分,因为这会涉及到 我如何在完成后获知已经完成。 所以,如果我把一个任务分解成一个子任务, 然后子任务非常简单, 我知道该如何完成--然后我将会完成该子任务。 我将会实施该子任务,并进行测试和记录。 然后,我可以将其重新组装回去。 但如果它仍然太复杂, 我将再次进行分解。 所以我们可以讨论诸如停止、直行和转弯之类的任务。 我可以分解模块。 我可以将其分解成子模块。 如果它们太复杂, 我将再次进行分解。 例如,对于线路传感器-- 这是我可能会用到的传感器之一。 如果我不知道如何实施线路传感器 我将会将其分解成多个部分,比如,实施输出, 等待一毫秒, 实施输入,然后进行思考。 现在我将这个线路传感器 分解成了多个子模块,简化到了我能够完成的程度。 然后,我将会实施这四个步骤, 然后将其重组回去。 需要注意的是,有时您遇到一个问题-- 这是一个问题-- 我将其分成两部分-- A1 和 A2。 然后我向前走,哒哒,我走对了。 但是还有一种可能,在您将 A 分成两部分后, 这部分,A1,可能实际上比原来的部分更难了。 因此,将一个对象分成两半,并不代表 它就会变简单。 这整整 1 万小时,或者说一百万行的代码 真的能让您擅长回答,如何才能 更有效且更高效的完成这项工作? 但是现在,我想让您考虑这个问题, 如果在将问题分解后,它变得比开始时 更复杂了,我将会将其重组回去, 并使用另外一些方式对其进行分解, 我将会持续尝试不同的分解方法, 直到子部分比初始任务更简单为止。 然后,我们会将这些子部分全部都重组回去。 我们知道,不管是对于数据流图, 还是调用图--这是一个数据流图, 我们知道,我们的工作是将其分解为 不同的部分,从而得到尽可能多的模块。 但是,我们会有较小的带宽。 也就是说,模块之间的 信息传输速率应尽可能低。 最终,与这个性质类似的是, 接口将会变得至关重要。 对于数据流图,是由这个接口 来传递数据。 对于调用图,模块 A调用模块 B。 同样,这个接口将会非常重要。 所以,当我将某个东西分解成子模块时, 这些模块如何重新连接对于确保系统 有效性和高效性至关重要。 因此,让我们找出一种定义接口的方法。 如果该接口 非常重要,我们将会 收集有关该接口的所有信息, 并将其存储在一处。 这便是我们的头文件。 同样,系统的模块化性质-- 该模块的开关--将具有两个文件-- 一个是 switch.c,包含实施信息, 另一个是 switch.h,包含公有函数的 原型。 也就是说,该文件包含接口。 它包含一个可以在该模块中 调用的函数的列表。 这样,我们就可以将该模块的功能分离出来。 比如,这是一个简单的模块,您可以 从开关进行输入。 您可以将其打开,然后您可以输入。 您将把这一点与它实际的工作方式分离。 它连接到什么端口,电压是什么, 它是正逻辑还是负逻辑-- 所有这些低层次细节都将被分离出来。 这种分离将会对降低系统 复杂性大有帮助。 这便是我们在这里提到的 复杂性抽象。 换句话说,我们将分离并隐藏 所有的低层次细节,并暴露给其他模块 一个可用于使用该模块的简单接口。 同样,包含在头文件中的是 公有函数的原型以及关于头文件-- 也就是该模块的功能和使用方式的注释。 未包含在该模块中的是该模块的工作方式。 模块内容的细节不包含在这里。 我们不会将任何变量放在头文件中。 这种私有概念全部属于内部运作。 注意这个头文件--实际上, 本课程中的所有头文件-- 都使用了这种奇异的语法,其中这是参数, 这是返回参数, 这是有关其功能的简短解释。 这种语法实际上叫做 doxygen。 doxygen 最厉害的地方就在于,它会自动 为整个机器人系统生成用户手册-- 一种软件文档。 您将会看到,大多数这种文档 都代表了您需要在本课程中编写的函数。 我们将会为您提供几个函数, 来支持您开始编写自己的函数。 所以这个 doxygen 流程可帮助我们 创建一个美观的 HTML 页面,用来介绍 软件的所有功能-- 也就是说,介绍它的功能, 而不介绍它的实际工作方式。 一个模块具有一个 .c 文件和一个 .h 文件。 我们说过,.h 文件中包含的是 公有函数的原型。 代码文件中包含的是实际的实施。 我们将会在下面的模块中讨论端口的 实际工作方式。 但是在这里,我们只需要知道 c 文件中包含的是 实际的工作方式,实际的实施是在 这里。 我们需要变量。 它在 c 文件中。 如果我们有任何特殊私有函数, 它也会在 c 文件中。 c 文件中的注释会介绍该函数的工作方式, 它是如何进行测试的,或者您可以如何更改该函数。 一定要非常谨慎地对待其他模块的 私有性质。 不要尝试访问其他模块的 私有信息或私有函数。 如果您在 Code ComposerStudio 中查看该项目, 您将会看到与该项目关联的所有文件。 但是如果您查看文件中的内容-- 例如,这里的这个文件,它是一个高级文件。 这段代码便是在该文件中。 最终,这里的这些 include 文件 实际上等效于或者将为您绘制 调用图。 如果这个函数包含那个函数的头文件, 那么我们便可以调用它的公有函数。 由于这里的这个 main c文件包含 LaunchPad.h, 所以它可以调用后者的公有函数。 所以这个 include文件是这个箭头。 这里的这个 include 文件-- 这是这个箭头。 所以这种将某个事物分解成模块的做法 对于简化非常复杂的系统大有帮助。 所以,当我们组建成我们的机器人时, 您会发现它包含数十个模块,所有模块均融入到 这个层次结构中。 最后总结一下,我们定义了模块化, 这是一个增加 模块总数的过程。 但是我们希望最大限度地减小带宽,互联, 每秒在不同模块之间 传输的字节数。 我们讨论了头文件。 头文件中包含的是接口-- 数据的流动方式,或者调用函数的 方式。 通过这种方式,我们可以分离其功能-- 高级交互-- 分离其功能和工作方式。 这样,我们将能够打造一个非常复杂的系统 所以随着向后面的部分推进,我们需要考虑该模型。 在本课程开始时,可能会很简单, 这时您实际上还不需要使用模块。 但是,当后面变得越来越复杂, 您将会看到使用模块化设计的好处。 好的。 在下一个模块中-- 下一个讲座中,我们将讨论一些 C 语法, 然后,我们将讨论一些调试方法。 好的。 稍后回来。401
课程介绍 共计5课时,27分54秒

TI-RSLK 模块 4 - 使用 MSP432 进行软件设计

TI 机器人 MSP432 软件设计 RSLK

此模块除了讲解使用 MSP432 和 TI Code Composer Studio™ 进行编译和调试的概念外,还介绍了 C 语言(一种通用编程语言)。在开发与机器人相关的复杂系统时,调试技能很重要。

  • 相关产品
  • 样品申请
  • EVM购买
  • 文档下载
  • 软件/工具
  • TI Design
分享到X
微博
QQ
QQ空间
微信

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新文章 手机版

站点相关: EEWORLD首页 EE大学堂 论坛 下载中心 Datasheet 活动专区 博客

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2017 EEWORLD.com.cn, Inc. All rights reserved