当前位置:  编程技术>移动开发
本页文章导读:
    ▪MQX3.8源代码分析:GPIO(五)驱动安装函数 _io_dev_install_ext()        MQX3.8源代码分析:GPIO(5)驱动安装函数 _io_dev_install_ext()这一节中,我们重点分析一下驱动安装函数_io_dev_install_ext(xxx),看看驱动安装到底都做了些什么工作,又会遇到哪些新的东西! 文件:.........
    ▪ Activity 通讯之:传入与返回信息        Activity 通信之:传入与返回信息转载请注明出处 谢谢!http://blog.csdn.net/metalseed/article/details/8197798 多Activity 需要建立多个java的class及相对应的xml 建立完成之后必须在manifest中注册 <acti.........
    ▪ Open Street Map维基世界map初探-概念、开发       Open Street Map维基世界地图初探--概念、开发 1. 什么是open street map(osm)? 2. 开发者应该知道哪些概念?包括地图的内容、格式等 3. OSM开发有哪些环境? 4. libosmscout环境的搭建 5. libosmscout的使用.........

[1]MQX3.8源代码分析:GPIO(五)驱动安装函数 _io_dev_install_ext()
    来源: 互联网  发布时间: 2014-02-18
MQX3.8源代码分析:GPIO(5)驱动安装函数 _io_dev_install_ext()

这一节中,我们重点分析一下驱动安装函数_io_dev_install_ext(xxx),看看驱动安装到底都做了些什么工作,又会遇到哪些新的东西!

文件:Io_instx.c (source\io)中

/*FUNCTION*-------------------------------
* 
* Function Name    : _io_dev_install_ext
* Returned Value   : _mqx_uint a task error code or MQX_OK
* Comments         :
*    Install a device dynamically, so tasks can fopen to it. Different from
* _io_dev_install since this function also installs an unstall function.
*
*END*----------------------------------*/

_mqx_uint _io_dev_install_ext
   (
      /* [IN] A string that identifies the device for fopen */
      char_ptr             identifier,
  
      /* [IN] The I/O open function */
      _mqx_int (_CODE_PTR_ io_open)(MQX_FILE_PTR, char _PTR_, char _PTR_),

      /* [IN] The I/O close function */
      _mqx_int (_CODE_PTR_ io_close)(MQX_FILE_PTR),

      /* [IN] The I/O read function */
      _mqx_int (_CODE_PTR_ io_read)(MQX_FILE_PTR, char _PTR_, _mqx_int),

      /* [IN] The I/O write function */
      _mqx_int (_CODE_PTR_ io_write)(MQX_FILE_PTR, char _PTR_, _mqx_int),

      /* [IN] The I/O ioctl function */
      _mqx_int (_CODE_PTR_ io_ioctl)(MQX_FILE_PTR, _mqx_uint, pointer),

      /* [IN] The I/O un-install function */
      _mqx_int (_CODE_PTR_ io_uninstall)(IO_DEVICE_STRUCT_PTR),

      /* [IN] The I/O initialization data */
      pointer              io_init_data_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   IO_DEVICE_STRUCT_PTR   dev_ptr;
#if MQX_CHECK_ERRORS
   _mqx_uint              i;
   _mqx_uint              found = 0;
#endif

   _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
   if ((io_open == NULL) || (io_close == NULL)){
      return(MQX_INVALID_PARAMETER);
   } /* Endif */

   /* Search for delimiter */
   for (i = 0; i < IO_MAXIMUM_NAME_LENGTH; i++) 
   	{
      if (identifier[i] == IO_DEV_DELIMITER) 
	  {
         found++;
      }
	  else if (identifier[i] == '\0') 
	  {
         break;
      } /* Endif */
   } /* Endfor */
      
   /* 
   ** Return an error if more than 1 delimiter found, no delimiter was found
   ** or the identifier was composed of a single delimiter only.
   */
   if ((found != 1) || (i == 1)) {
      return(MQX_INVALID_PARAMETER);
   } /* Endif */
/* START CR-169 */
#endif

   /* Check to see if device already installed */
   _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   if (kernel_data->IO_DEVICES.NEXT == NULL) {
      /* Set up the device driver queue */
      _QUEUE_INIT(&kernel_data->IO_DEVICES, 0);
   } /* Endif */

#if MQX_CHECK_ERRORS
   dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)kernel_data->IO_DEVICES.NEXT);
   while (dev_ptr != (pointer)&kernel_data->IO_DEVICES.NEXT) {
      if (!strncmp(identifier, dev_ptr->IDENTIFIER, IO_MAXIMUM_NAME_LENGTH)) {
         _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
         return(IO_DEVICE_EXISTS);
      } /* Endif */
      dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)dev_ptr->QUEUE_ELEMENT.NEXT);
   } /* Endwhile */
#endif
   _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
/* END CR-169 */
   
   dev_ptr = (IO_DEVICE_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)
      sizeof(IO_DEVICE_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (dev_ptr == NULL) {
      return(MQX_OUT_OF_MEMORY);
   }/* Endif */
#endif
   _mem_set_type(dev_ptr, MEM_TYPE_IO_DEVICE);
      
   dev_ptr->IDENTIFIER      = identifier;
   dev_ptr->IO_OPEN         = io_open;
   dev_ptr->IO_CLOSE        = io_close;
   dev_ptr->IO_READ         = io_read;
   dev_ptr->IO_WRITE        = io_write;
   dev_ptr->IO_IOCTL        = io_ioctl;
   dev_ptr->IO_UNINSTALL    = io_uninstall;
   dev_ptr->DRIVER_INIT_PTR = io_init_data_ptr;

   _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
   _QUEUE_ENQUEUE(&kernel_data->IO_DEVICES, dev_ptr);
   _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);

   return MQX_OK;

} /* Endbody */

分析:

        首先传递参数有gpio的驱动标示符identifier,一般是“gpio:”,还有驱动操作函数指针,这个上次已经讲过了,剩下的那个就是初始化数据的指针,一般是传递一些特殊数据,这里设为NULL。

        然后定义了两个变量:内核数据kernel_data和io设备指针dev_ptr,内核数据指针指向的数据主要包含系统内核状态信息,是一个全局变量,供各个模块使用。设备指针主要包含我们马上就要初始化的一些数据信息,下面会看到初始化的过程就是初始化这个dev_ptr指针,然后把这个指针链接进kernel_data的过程,这样系统就获得了GPIO的操作函数,完成初始化。

       紧接着是宏定义MQX_CHECK_ERRORS,用户可以打开这个宏,进行参数的有效性校验,对不符合的参数进行错误处理,一般这个宏都是打开的,这才符合高质量编程的规范嘛!

        下一步,获得信号量来保证初始化操作的互斥性,进一步检测kernel_data中的io设备结构体队列是否初始化,如果没有初始化(IO_DEVICES.NEXT = NULL),则先进行io设备队列的初始化。下面这个while循环,主要是判断在IO列表上是否已经存在初始化好的的io设备结构体,判断的根据就是传递过来的identifier标示符“GPIO:”。如果存在,就返回错误信息。

         信号量使用完成后一定要释放,这是特别要注意的。当入口校验完毕,下一步就是进行dev_ptr结构体的初始化了,首先以初始化为0的方式分配内存空间,空间IO设备结构体大小。注意,一般在分配内存空间时,都需要进行空间分配是否成功的判断,因为分配内存会有分配失败的可能存在。但是我记得在学习linux时,linux也需要判断,而且linux返回的值也都是几乎都正确,因为linux在分配时,分配的并不是实际地址,而是一个逻辑地址,当对该空间操作时,才进行逻辑地址向屋里地址的映射。这里不是mqx是不是这样,不管是不是都需要判断,这是少不了的。

        最后,进行dev_ptr结构体的初始化,给里边的各个变量赋值,把相关的io操作函数进行绑定。绑定完成后,再把设备结构体链接到内核数据结构上,这样内核数据结构就可以根据一个io结构体,找到对应的io操作函数,这样就完成了GPIO驱动函数与MQX内核之间的数据映射,下一步要做的工作就是根据GPIO硬件属性,完成对应驱动函数的功能实现了。

至于MQX内核是怎样进行相关函数调用,组合内部逻辑的,这个我们暂时还看不到迹象,或许以后可以看到!另:该函数里边用到了许多队列相关知识,而且大概看了一下,队列的使用中有好多技巧值得我们学习,故下一步要详细分析一下啦!


    
[2] Activity 通讯之:传入与返回信息
    来源: 互联网  发布时间: 2014-02-18
Activity 通信之:传入与返回信息

转载请注明出处 谢谢!http://blog.csdn.net/metalseed/article/details/8197798

多Activity 需要建立多个java的class及相对应的xml

建立完成之后必须在manifest中注册

        <activity
            android:name=".activity2"
            android:label="@string/MSSSS" >
        </activity>

普通String的传入:

主调程序中:

(将名为将"Seed"以名为Name的String丢给被调用程序)

        Button1.setOnClickListener(new View.OnClickListener(){
        	public void onClick(View V){
        		Intent intent = new Intent(MainActivity.this, activity2.class);
        		String name = "Seed";
        		intent.putExtra("Name", name);
        		satrtActivity(intent);
        	}
        });

被调程序:

(获取名为Name的String)

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity2);
        Intent intent = this.getIntent();
        String message = intent.getStringExtra("Name");
    }


传递对象类型


Activity回传数据
1:把名为Name的String丢给被掉程序(用startActivityForResult)
        Button1.setOnClickListener(new View.OnClickListener(){
        	public void onClick(View V){
        		Intent intent = new Intent(MainActivity.this, activity2.class);
        		String name = "Seed";
        		intent.putExtra("Name", name);
        		startActivityForResult(intent, 1);
        	}
        });
2:在被调Activity中重写finish来设置返回信息
(把名为rtString的String附带在返回intent中,并且回传标记为activity2Return)(用bundle携带)
    @Override
    public void finish(){
    	Intent intent = new Intent();
    	Bundle b = new Bundle();
    	b.putString("rtString","~~~~");
    	intent.putExtras(b);
    	setResult(activity2Return, intent);
    	super.finish();
    }
3:在主调程序中重载onActivityResult,获得回传的message
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
    	switch(resultCode){
    	case activity2Return:
    		Bundle b = data.getExtras();
    		String returnMessage = b.getString("ac2");
    	}
    }





    
[3] Open Street Map维基世界map初探-概念、开发
    来源: 互联网  发布时间: 2014-02-18
Open Street Map维基世界地图初探--概念、开发


1. 什么是open street map(osm)?

2. 开发者应该知道哪些概念?包括地图的内容、格式等

3. OSM开发有哪些环境?

4. libosmscout环境的搭建

5. libosmscout的使用示例、配置文件


1. 什么是OSM?

Open Street Map 维基世界地图,一个开源的在线地图项目,包括软件和地图数据。

官网介绍

http://wiki.openstreetmap.org/wiki/Zh-hans:Main_Page

中文网页

http://wiki.openstreetmap.org/wiki/Main_Page

OSM与其他地图 如google地图的区别在哪里?

正如官网所说,它提供了一种方式,让任何人能编辑地图,能为OSM增加地图数据(当然如果是错误的,别人是有权修改的)。而且,其他地图大部分都不是免费的,或者需要授权使用, google地图是免费的,但它也是被别人授权的,无法随意编辑或在自己的软件中使用的。

所以,人们也可以免费地使用OSM数据,包括开发等。


对OSM的常见问题,可以浏览

http://wiki.openstreetmap.org/wiki/FAQ


对于大部分人而言,为OSM绘图是比较有趣的事。

有关为地图增加数据(绘图)的详细介绍如下:

http://wiki.openstreetmap.org/wiki/Zh-hans:Map_Making_Overview


而对于开发者而言,更关心如何使用OSM数据,用于开发,一个必要的开发介绍和资源入口:

http://wiki.openstreetmap.org/wiki/Develop

里面介绍了 OSM的API, 如何下载map data,map data的数据格式和数据结构,常用的开发工具(已经开发好的小工具),地图要素(有哪些数据),与OSM相关的支持的框架(库和组件)。


OSM自身的框架描述:

http://wiki.openstreetmap.org/wiki/Component_overview


下面先介绍一些与开发相关的概念和环境。

2. OSM相关的一些概念

地图数据的存储方式是xml结构,后缀名可以是xml或osm。


地图的数据结构,即地图要素包括1 Node, 2 Way, 3 Relation,4 Tag,5 Common attributes

这些地图要素,与普通的地图或导航要素概念相同

Node是空间点,包括经纬坐标,或高度信息。其他一些可选信息,如name等,在tag子数据中表示。类似于shape point 或attribution point

way表示线或区域,能包含2-2000个node点信息。它道路与区域描述的主要形式。类似于link、edge的概念

relation表示不同的元素间的关系,将不同元素间的关系描述出来。类似于connection的概念

tag表示一个元素中包含的一个特征,或者说是包含的一小块数据,如highway=residential,住宅区内的道路。类似于attribution的概念,不过tag的作用远不止attribution的描述。

Common attributes就是node、way、relation的共同属性,包括id, usr, version, timestamp等meta的信息。

更详细的描述参见:

http://wiki.openstreetmap.org/wiki/Data_Primitives

及每个元素的子链接。


有关tag类型的详细介绍和分类在这里有介绍:

http://wiki.openstreetmap.org/wiki/Map_Features


3. 开发框架

OSM目前提供了API 0.6版本的开发接口,xapi是extended api扩展的接口。而这些接口是用于web或java应用开发的。如下介绍

http://wiki.openstreetmap.org/wiki/Databases_and_data_access_APIs

如果是使用其他语言开发,就必须使用其他的库或组件,这里列举了各种语言支持的库和组件。

http://wiki.openstreetmap.org/wiki/Develop/Frameworks


对于我而言,我采用的c++开发语言,目的是读取OSM数据,并解析,选取一些数据,我就选用libosmscout库。

所以,下面我就介绍libosmscout的开发环境设置。


4. libosmscout环境的搭建

我使用JOSM用于查看和下载地图数据,JOSM只能查看较小的地图数据,其内存支持400多MB,对于更大的数据不支持。OSMOSIS用于数据转换或分割等。

地图数据下载,以下链接里包括各个地区或整个地图的下载路径:

http://wiki.openstreetmap.org/wiki/Planet.osm


libosmscout各个模块的介绍: 

http://wiki.openstreetmap.org/wiki/Libosmscout

闲话少说,环境搭建(非qt版部分):

a. 使用git从sourceforge上把源码都下载下来

http://sourceforge.net/projects/libosmscout/

b. libosmscout支持windows版本,我使用的是vs2008,所以首先查看README.VisualStudio.txt,里面包含了详细的build windows版本的步骤。

c. 依据readme,将zlib、libxml2、google protocol buffers、protoc.exe下载下来,并配置好。其中zlib、libxml2的版本要匹配,否则会有很因为版本不匹配的链接错误。

d. 依据readme,设置环境变量EXTRALIBS_HEADERS、EXTRALIBS_DEBUGLIBS。

e. 然后编译,这时,若有与DECLARE_COEFFS(SINECOEFF_SSE)相关的编译错误,就查看SSEMath.cpp中,有关math的一系列代码是否是有效的,若无效,加入#define OSMSCOUT_HAVE_SSE2。这个是我遇到的其vs工程中自带的问题,可能是个小bug吧。

f. 此时libosmscout工程、libosmscout-import工程、import工程、demo_AddressLookup工程都能编译通过。有关qt部分的工程我没编译,这里就不写了。


订阅邮件列表,用于知晓它的修改变换,及咨询问题:

https://lists.sourceforge.net/lists/listinfo/libosmscout-development


5. libosmscout使用示例与配置

在使用demo_AddressLookup之前,要获取OSM地图数据及将osm地图数据转换为libosmscout需要的binary数据。

如果手上拿的的有xml格式的数据,可以使用osmosis工具将xml格式的数据转换为osm格式。转换命令示例:

osmosis --read-xml file="planetin.xml" --write-xml file="planetout.osm"
更丰富的,强大的示例在

http://wiki.openstreetmap.org/wiki/Osmosis#Example_Usage

或使用JOSM工具从服务器上下载地图数据,并保存为osm格式,这种方法能直接打开地图数据并查看。


然后,使用编译好的import.exe,将osm格式的数据转换为binary数据。在运行程序之前,将libosmscout\map.ost复制到程序当前目录下,因为import需要默认的map.ost参数文件。建立一个用于输出结果的文件夹(libosmscout的binary地图作为输入或输出都是文件夹的形式),如转换planet.xml,运行命令Import.exe planetout.osm --destinationDirectory planet

更详尽的命令参数,请参看源码或import的命令提示。

import的输出会包含很多dat和idx文件,dat是数据文件,idx是dat的索引文件,更详细的说明在libosmscout\libosmscout\ProcessResult.txt中,libosmscout\libosmscout\Resource.txt是一些算法和程序所占资源的说明。

并且map.ost是可以编辑的,可以增加或删除一些选项,如以下一些必要类型保留,其他我都删除,并添加了highway_crossing类型。这样能减少自己不需要的生成的binary数据,当然就会提高效率。

OST

TYPES
  TYPE "highway_crossing" = NODE ("highway"=="crossing") 

  // Do not delete the following type, they are required by the GenCityStreet import step
  TYPE "boundary_administrative" = WAY AREA ("boundary"=="administrative") OR
                                   RELATION ("type"=="boundary" AND "boundary"=="administrative") OPTIONS MULTIPOLYGON IGNORESEALAND

  // Do not delete the following types, they are required by the GenCityStreet import step
  TYPE "place_city" = NODE AREA ("place"=="city")
  TYPE "place_town" = NODE AREA ("place"=="town")
  TYPE "place_village" = NODE AREA ("place"=="village")
  TYPE "place_hamlet" = NODE AREA ("place"=="hamlet")
  TYPE "place_suburb" = NODE AREA ("place"=="suburb")

END

自己的一个小的demo,打印地图中highway_crossing的node(前提:自己生成的输入地图中有highway_crossing的数据)。

#include <iostream>
#include <iomanip>
#include <vector>

#include <osmscout/Database.h>
#include <osmscout/TypeConfigLoader.h>

using namespace std;
const static size_t RESULT_SET_MAX_SIZE = 1000;

int main(int argc, char* argv[])
{
  std::string                      map;
  map=argv[1];

  osmscout::DatabaseParameter databaseParameter;
  //databaseParameter.SetDebugPerformance(true);
  osmscout::Database          database(databaseParameter);

  if (!database.Open(map.c_str())) {
    std::cerr << "Cannot open database" << std::endl;

    return 1;
  }

  double minlat = 0.f;
  double minlon = 0.f;
  double maxlat = 0.f;
  double maxlon = 0.f;
  database.GetBoundingBox(minlat, minlon, maxlat, maxlon);

  std::cout << " " << minlat << " " << minlon << " " << maxlat << " " << maxlon << std::endl;

  std::vector<osmscout::NodeRef> nodes;
  std::vector<osmscout::WayRef> ways;
  std::vector<osmscout::WayRef> areas;
  std::vector<osmscout::RelationRef> relationWays;
  std::vector<osmscout::RelationRef> relationAreas;

  osmscout::TypeConfig typeConfig;

  clock_t startTime = clock();

  if (!osmscout::LoadTypeData(map,typeConfig)) {
      std::cerr << "Cannot load 'types.dat'!" << std::endl;
      return false;
    }
    std::cout << "typeID:" << typeConfig.GetTypeId("highway_crossing") << endl;

  osmscout::TypeSet types;
  types.SetType(typeConfig.GetTypeId("highway_crossing"));
  std::cout << types.HasTypes() << std::endl;

  database.GetObjects(minlon, minlat, maxlon, maxlat,types, nodes, ways, areas, relationWays, relationAreas);
  clock_t endTime = clock();

  std::cout << "Time:" << (endTime - startTime) << std::endl;

  std::cout << "nodes: " << nodes.size() << " ways:" << ways.size() << " areas:" << areas.size() << std::endl  
      << "relationWays:" << relationWays.size() << " relationAreas:" << relationAreas.size() << std::endl;

  for (unsigned int i=0; i<nodes.size(); ++i)
  {
      std::cout << i << "GetLat:" << nodes[i].Get()->GetLat() << std::endl;
      std::cout << i << "GetLon:" << nodes[i].Get()->GetLon() << std::endl;
      std::cout << i << "GetId:         " << nodes[i].Get()->GetId() << std::endl;
      if (nodes[i].Get()->GetTagCount() > 0)
      {
          std::cout << i << "GetTagCount:" << nodes[i].Get()->GetTagCount() << std::endl;
          std::cout << i << "GetTagKey:" << nodes[i].Get()->GetTagKey(0) << std::endl;
          std::cout << i << "GetTagValue:" << nodes[i].Get()->GetTagValue(0) << std::endl;
      }
      std::cout << i << "GetType:" << nodes[i].Get()->GetType() << std::endl;
  }

  database.Close();

  std::cout << "database close ..." << std::endl;

  return 0;
}


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3