Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1135394
  • 博文数量: 86
  • 博客积分: 667
  • 博客等级: 上士
  • 技术积分: 1472
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-27 15:59
个人简介

一沙一世界

文章分类

全部博文(86)

文章存档

2020年(9)

2019年(8)

2017年(3)

2016年(11)

2015年(17)

2014年(9)

2013年(4)

2012年(19)

2011年(1)

2009年(4)

分类: LINUX

2016-02-23 15:31:49

今天看看px4log部分,log这部分其实是比较独立的模块,是可以拿出来使用在其它场合的。基本上也就是一般的记录日志的那一套形式。
不过也记录下来吧。这里没有粘贴代码,一行一行说明,但是下面的内容和代码是一一对应的。

首先根据rcS,它启动rc.logging,那咱们就看看这个脚本:

if [ -d /fs/microsd ]

then

         if ver hwcmp PX4FMU_V1

         then

                   if sdlog2 start -r 40 -a -b 3 -t

                   then

                   fi

         else

                   if sdlog2 start -r 100 -a -b 12 -t

                   then

                   fi

         fi

fi

可见,只是启动sdlog2这个命令。后面那一堆都是参数。接下来看代码了。

Src/modules/sdlog2/sdlog2.c,找到sdlog2_thread_main函数,这个是入口。前面一段是参数分析,稍微看下这段:

r参数写入日志频率,对于fmuv2来说,频率是100Hz,即每10ms执行一次。

b参数是log buffer大小,对于fmuv2来说,是12kB

a参数表示当系统armed以后,开始记录日志。

t参数表示日志文件名字中含有时间戳信息。

然后下面初始化了日志模块接收信息的结构体或者联合体。注释里也说了主要是为了节省空间。

#pragam packpush 1

.。。。。。。

#pragram packpop

这个大家可以baidu下看看,其实也是为了节省空间,主要是对齐方面的设置。

然后初始化的了线程锁和线程条件变量。接下来呢,进入while循环。记录日志的周期在一进入循环就体现了:sleep,不用太过精确,日志记录这件事情啊,和其它的高精度定时相比较,时间多一点,少一点,不是很重要,睡一会醒来接着干活即可。

下面的循环的几个checkupdate,这几个主要是检测是否需要根据特定的系统要求启动日志写线程。并且只是写线程正常启动以后,才继续往下执行。

在往下继续写以前呢,说下记录日志这件事的软件结构。那就是一个循环缓存区+线程锁+条件变量。还得+两个指针:读指针和写指针。根据这几个组成部分大家也应该知道软件流程了。

一个线程向缓冲区写入日志信息,另外的一个线程从这个缓冲区读日志信息写到sd卡上。两个线程的互斥和同步通过线程锁和条件变量来实现。

sd卡的是子线程是logwriter_thread,这个线程没有什么说的,就是获得线程锁,查看是否有数据可写到sd卡?没有活干就wait,在条件变量上等待有活干。如果有活干了,先释放线程锁,然后把日志信息写到sd卡,然后再次循环,在线程锁锁住前提下修改指针,继续检查是否有日志信息可以继续写到sd卡。好了,没有了,就这么多。这里需要注意下,循环缓冲区的使用。网上找到看看就可以,或者linux内核代码中好像是有个fifo.c的文件,实现原理一样。这是子线程干的活,再回头看看父线程干毛?其实不用看也知道,子线程有活干,其实是父线程提供的活,父线程的活就是向循环队列里写入日志内容。

大体结构如下:

While()

{

         Sleep()

         All kinds of check and update

         log_msg.xxxx = yyyy;

         …….

         LOGBUFFER_WRITE_AND_COUNT

}

详细不说了,没有其它。

阅读(1619) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~