大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是MCUXpresso IDE下将源码制作成Lib库方法及其与IAR,MDK差异。
程序函数库是一个包含已经编译好代码和数据的函数集合,这个库文件里的函数可以供其他程序调用。被放进库文件里的代码通常具有一定通用性,是经过高度抽象的,这样可以避免重复造轮子。程序函数库设计可以使得程序的开发工作更加模块化,更容易重新编译,也更方便升级。
嵌入式开发里有时候也会需要涉及函数库文件,除了模块化开发以及方便升级特点外,有时候也是为了对源代码进行保密,毕竟库文件是编译后的文件。今天痞子衡就跟大家聊聊 MCUXpresso IDE 下生成 Lib 库文件的方法及其与 IAR, MDK 有何差异。
- Note: 痞子衡测试的MCUXpresso IDE版本是v11.4.0_6224。
我们先来看看其它 IDE 下是如何生成和使用 Lib 库文件的。我们以 \SDK_2.10.0_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\hello_world\cm7 目录下的工程文件为例。这个 hello_world 例程主要就是利用 LPUART 外设驱动( fsl_lpuart.c )实现串口打印功能,这里我们就尝试将 fsl_lpuart.c 文件制作成 Lib 库(这里特指静态链接库 - Static Library)。
使用 IAR 打开 hello_world_demo_cm7.eww 文件,编译默认工程可以得到工程可执行文件和镜像文件,这是经过编译和链接之后的可直接执行的纯机器码数据。由于我们只需要将 fsl_lpuart.c 文件制作成 Lib 库,所以要对工程进行一些改动:
1. 将工程里除 fsl_lpuart.c 之外的其它 .c 文件全部移除,并且仅需保留 fsl_lpuart.c 所依赖的相关头文件。
2. 在工程选项 General Options / Output / Output file 里切换到 Library。
3. 在工程选项 Library Builder / Output / Output file 里命名生成的库文件(比如 lpuart_drv.a )。
这时候重新编译工程便可以得到我们想要的 lpuart_drv.a 库文件,如果要使用这个库文件的话,也非常简单,只要在原始的 hello_world 工程里将 fsl_lpuart.c 文件替换成 lpuart_drv.a 即可。
MDK 下制作和使用 Lib 库方法与 IAR 差不多,就是工程设置差异。使用 MDK 打开 hello_world_demo_cm7.uvprojx 文件,同样对工程进行一些改动:
1. 将工程里除 fsl_lpuart.c 之外的其它 .c 文件全部移除,并且仅需保留 fsl_lpuart.c 所依赖的相关头文件。
2. 在工程选项 Output / 里切换到 Create Library。
3. 在工程选项 Output / Name of Executable 里命名生成的库文件(比如 lpuart_drv.lib )。
了解了 IAR, MDK 下制作和使用 Lib 库方法,我们再来看本文的主角 MCUXpresso IDE 下制作 Lib 库的方法。首先是按照 《MCUXpresso IDE下SDK工程导入与workspace管理机制》 一文导入一个 hello_world 工程,在导入向导界面,我们能看到 SDK 里的例程类型是 C Project,旁边虽然有 C Static Library 选项,但是不可设置。
我们先使用 SDK 包里导出的默认工程(C Project),按照之前 IAR, MDK 上的经验,在这个工程里做如下改动。重新编译工程,发现生成的文件似乎跟原始工程生成的可执行文件(Artifact Type 为 Executable )差不多,显然 Shared Library 并不是我们想要的静态 Lib 库。
1. 将工程里除 fsl_lpuart.c 之外的其它 .c 文件全部移除,并且仅需保留 fsl_lpuart.c 所依赖的相关头文件。
2. 在工程选项 C/C++ Build / Settings / Build Artifact / Artifact Type 里切换到 Shared Library。
3. 在工程选项 C/C++ Build / Settings / Tool Settings / MCU Linker / Shared Library Settings 里 Shared 选项勾选上。
那么 MCUXpresso IDE 下如何生成静态 Lib 库呢?很遗憾,你必须在新建工程之初就确定工程类型为 C Static Library,工程类型确定之后无法仅通过工程选项来切换 C Project 和 C Static Library (这是和 IAR, MDK 不一样的第一个地方)。在创建 C Static Library 时尽量在向导里将多余的源文件选项全部去掉,仅保留我们感兴趣的 lpuart 驱动。
新建了 C Static Library 工程后发现工程里还是残留了多余的 .c 文件(Debug Console 和 device 初始化相关文件),这时候再手动移除这些 .c 文件,然后打开工程选项 C/C++ Build / Settings / Build Artifact / Artifact Type,此时仅有 Static Library 一种选择。编译工程可得到 liblpuart_drv.a 文件(MCUXpresso IDE 特意在用户设置的库名加了 lib 前缀,这是刻意设计的,后面使用该库文件时会用到这个设计),即是我们需要的静态 Lib 库文件。
回到官方 SDK 包里原始的 hello world 例程里,此时我们尝试使用这个 liblpuart_drv.a 文件,我们将工程目录下的 fsl_lpuart.c 文件替换成 liblpuart_drv.a 文件,直接编译发现报错,无法找到 LPUART 相关驱动,显然工程并没有直接识别库文件(这是跟 IAR, MDK 不一样的第二个地方),这时候需要更新下工程选项,在 C/C++ Build / Settings / Tool Settings / MCU Linker / Libraries 里添加 liblpuart_drv.a 库(包括名字和路径),这里特别注意库名字仅需要填 lpuart_drv,不需要 lib 前缀(这就是前面所说的 MCUXpresso IDE 特意设计)。此时再编译工程,就一切正常了。
在 MCUXpresso IDE 下我们接触到了两种库 Static Library 和 Shared Library,最后再简单介绍下它俩的差异。
静态库是一些 .o 目标文件的集合,一般以 .a/.lib 形式结尾。静态库在程序链接阶段使用,链接器将程序要用到的函数从库中提取出来,并整合到程序中,程序运行不再使用静态库了。由于每个程序要用到函数都从库提取并整合在一起,所以可执行文件会比较大。
共享库即动态链接库,在 Linux 中以 .so(share object) 为后缀,在 Windows 中以 .dll 为后缀。程序开始启动运行时,加载所需的函数,程序运行时也需要共享库的支持。共享库链接出来的文件比静态库要小得多。
所以这其实就是链接方式的差异,链接(Link)是程序被装载到内存运行之前需要完成的一个步骤。链接本身分为静态链接(Static Link)和动态链接(Dynamic Link)两种方式。而在嵌入式 MCU 世界里,我们通常都是用静态链接这种方式。
至此,MCUXpresso IDE下将源码制作成Lib库方法及其与IAR,MDK差异痞子衡便介绍完毕了,掌声在哪里~~~
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我创建了一个文件,这样我就可以在lib/foo/bar_woo.rb中的许多模型之间共享一个方法。在bar_woo.rb中,我定义了以下内容:moduleBarWoodefhelloputs"hello"endend然后在我的模型中我正在做类似的事情:defMyModel解释器提示它期望bar_woo.rb定义Foo::BarWoo。《使用Rails进行敏捷Web开发》一书指出,如果文件包含类或模块,并且文件使用类或模块名称的小写形式命名,那么Rails将自动加载文件。因此我不需要它。定义代码的正确方法是什么,在我的模型中调用代码的正确方法是什么? 最佳答案
在我的mac上安装几个东西时遇到这个问题,我认为这个问题来自将我的豹子升级到雪豹。我认为这个问题也与macports有关。/usr/local/lib/libz.1.dylib,filewasbuiltfori386whichisnotthearchitecturebeinglinked(x86_64)有什么想法吗?更新更具体地说,这发生在安装nokogirigem时日志看起来像:xslt_stylesheet.c:127:warning:passingargument1of‘Nokogiri_wrap_xml_document’withdifferentwidthduetoproto
我最近正在进行Rails5升级,当我尝试启动Rails控制台时遇到了这个错误:/actionpack-5.0.0/lib/action_controller/test_case.rb:49:ininitialize':wrongnumberofarguments(0for2)(ArgumentError)当前bundleupdaterails已经完成了gem依赖项的解决,足以更新到5.0.0,rspec正在运行(尽管我正在修复很多中断)。我也可以运行railss没有错误。这里是代码中断行:https://github.com/rails/rails/blob/master/action
我目前正在将Railsv2中的应用程序迁移到v3在我的lib/我在子目录中有一些模块,例如,我有lib/search/host_search.rb有一个moduleHostSearchdefdo_search(args)#...endend然后我需要在名为Discovery::HostController的Controller中使用它defsearch_resultsoutput=HostSearch.do_search(:search_string=>@search_string,:page=>params[:page],:user=>@current_user)#...end但是我
对于体育新闻中文文本的关键字提取,常用的算法包括TF-IDF、TextRank和LDA等。它们的基本步骤如下:1.TF-IDF算法: -将文本进行分词和词性标注处理。-统计每个词在文本中的词频(TF)。-计算每个词在整个语料库中出现的文档频率(DF)和逆文档频率(IDF)。-计算每个词的TF-IDF值,并按照值的大小进行排序,选择排名前几的词作为关键字。2.TextRank算法:-将文本进行分词和词性标注处理。-将分词结果转化成图模型,每个词语为节点,根据词语之间的共现关系建立边。-对图模型进行迭代计算,计算每个节点的PageRank值,表示该节点的重要性。-选择排名前几的节点作为关键字。3.
光度学中的能量、通量、出度、照度、强度、亮度参数及其联系光度学中评价光的强弱有两种方式,一种是将光作为电磁波,考察其辐射的能量;另一种是以人眼视觉体验来评价光的强弱。前者被称为辐射量,后者被称为光学量。辐射量包括辐射能、辐通量、辐出量、辐照度、辐强度、辐亮度参数,与之相对应,光学量包括光能量、光通量、光出量、光照度、光强度、光亮度参数。通过该文章的阅读,读者还能掌握光学中的几个单位:流明,勒克斯,坎德拉,尼特的意义以及他们之间的关系。辐射量1.辐射能光以电磁波形式发射、传输或接收的能量。单位:焦耳。2.辐通量单位时间发射、传输和接收的辐射能。单位:瓦特。3.辐出度单位面积的辐射源辐射出的辐通量
引用这个问题:Idealrubyprojectstructure我注意到appname.rb在lib中,并且是顶级。我在Github上阅读了一些Rake源代码,我注意到他们的项目结构几乎相同。他们在/lib中有一个顶级“rake.rb”文件,但我不确定它的用途。在ThePickaxe(ProgrammingRuby1.9)中,他们展示了一个构建小型项目的示例,其目录结构与上面几乎相同,但没有提及/lib中顶级.rb的用法。所以,我的问题是:这个东西在Ruby项目中通常用于什么?抱歉,如果这是一个愚蠢的问题,我敢肯定,但我对Ruby还比较陌生。我现在不太了解Ruby-foo。;)谢谢。
我了解到,在生产模式下预编译Assets期间,如果我们不明确需要任何其他特定来源的文件,Rails只会默认从“app/assets”获取Assets像“vendor/assets”和“lib/assets”。我有一个问题:Willrequire_tree.loadassetsfrom'vendor/assets'and'lib/assets'? 最佳答案 不,require_tree.只会加载本地目录中的Assets,因此require_tree之后的点仅指定应用程序Assets文件所在的目录。如果你想在vendor/assets和
我理解RubystdlibMatrix是不可修改的,也就是说,例如。m=Matrix.zero(3,4)不会写m[0,1]=7但我非常想做...我可以用笨拙的编程来做,比如defmodify_value_in_a_matrix(matrix,row,col,newval)ary=(0...m.row_size).map{|i|m.rowi}.map(&:to_a)ary[row][col]=newvalMatrix[*ary]end...或者作弊,比如Matrix.send:[]=,0,1,7但我想知道,这一定是人们一直遇到的问题。有没有一些标准的、习惯的方法可以做到这一点,而不必使用