3

概述:

我有一个 Python 程序,可以在 9 点到 5 点之间控制运动传感器。该程序在Raspberry Pi上运行,存储在带有 occidentals v2.1 Debian OS 的 SD 媒体上。该程序严重依赖 time.sleep 方法在非工作时间睡觉,并在第二天早上 9 点恢复工作。如果传感器触发,它会通过网络摄像头自动拍摄一张小照片。

问题:

直到最近该程序运行良好,直到有一天早上有人触发了传感器并且 take_picture() 函数无法初始化 /dev/video0。udev 似乎没有将设备映射到 /dev/video*,当我重新插入网络摄像头并使用“ dmesg | tail ”检查其状态时,我收到了一个错误:

[36725.201116] EXT4-fs error (device mmcblk0p2): udev

在研究了问题并得出这是文件系统损坏的结论后,我尝试在 SD 媒体上运行文件系统检查。在该过程中解决了许多错误,但重新安装 USB 网络摄像头后再次出现相同的 ext4-fs 错误消息。

修复尝试#1

此时我重新安装了操作系统并重新运行了我的传感器 Python 程序;两天它工作,发送图像,睡觉。我认为一切正常,所以我关闭了设备以将传感器放置在更集中的位置。

启动设备并简单地从SSHpython连接运行命令后,我收到此错误:

Traceback (most recent call last):
  File "/usr/lib/python2.7/site.py", line 562, in <module>
    main()
  File "/usr/lib/python2.7/site.py", line 544, in main
    known_paths = addusersitepackages(known_paths)
  File "/usr/lib/python2.7/site.py", line 271, in addusersitepackages
    user_site = getusersitepackages()
  File "/usr/lib/python2.7/site.py", line 246, in getusersitepackages
    user_base = getuserbase() # this will also set USER_BASE
  File "/usr/lib/python2.7/site.py", line 235, in getuserbase
    from sysconfig import get_config_var
ImportError: cannot import name get_config_var

在程序运行期间和我重新启动之后没有更改任何设置。我假设最坏的情况并再次检查“dmesg | tail”并收到更多文件系统错误:

[36725.201116] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21266: comm python: bad header/extent: invalid extent entries - magic f30a, entries 1, max 4(4), depth 0(0)
[36725.239030] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21427: comm python: bad header/extent: too large eh_max - magic f30a, entries 1, max 516(4), depth 0(0)

在额外的文件系统检查并重新启动后,运行python

[  819.427780] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21266: comm python: bad header/extent: invalid extent entries - magic f30a, entries 1, max 4(4), depth 0(0)
[  819.470874] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21427: comm python: bad header/extent: too large eh_max - magic f30a, entries 1, max 516(4), depth 0(0)
[  819.570893] EXT4-fs error (device mmcblk0p2): ext4_xattr_block_get:232: inode #21265: comm python: bad block 128

在这一点上,我认为这些错误的原因可能与我的程序的核心有关,但本质上它非常简单,只在创建图片时写入磁盘。下面是罪魁祸首代码:

有潜在问题的代码:

def take_picture():
    cam = pygame.camera.Camera("/dev/video0",(320,240))     #1280x960 max but slow
    pygame.init()
    cam.start()
    print "Capturing Image..."
    image_output = cam.get_image()
    pygame.image.save(image_output,'img_' +str(get_timestamp)+'.jpg')
    cam.stop()

# Activate PIR
def pir_init():
    while True:
        m = datetime.datetime.now().time().minute     #loop through for current time
        h = datetime.datetime.now().time().hour
        d = datetime.datetime.today().weekday()
        if d > 4:
            print("Sleeping...")
            print time_sleep
            time_sleep = (((7 - d) * 3600) * 24) - (h * 3600) + (9 * 3600)
            time.sleep(time_sleep)
        elif h < 9:
            print("Sleeping...")
            time_sleep = (9 - h) * 3600
            time.sleep(time_sleep)
        elif h > 16:
            print("Sleeping...")
            time_sleep = ((24 - h) + 9) * 3600
            time.sleep(time_sleep)
        elif io.input(pir_pin):
            print("PIR ALARM")
            pygame.camera.init()
            time.sleep(1.5)
            take_picture()
            send_gmail()
            time.sleep(10)      # Cooldown to prevent email spew
        else:
            print "Waiting..."
            time.sleep(0.5)     # Sleep and wait for movement
            print m
print "Wait"

我可以在上面看到的唯一潜在问题可能是生成图片或长时间休眠。

什么可能导致这些重复的文件系统错误?

4

1 回答 1

5

It is pretty common for SD cards to become corrupt on the Raspberry Pi and this code would not directly be able to cause this.

The only reason I think that the code would be causing problems that I see is if it tries to write to the SD card too often, which is unlikely and most likely caused by an underlying issue. Maybe the SD card is going bad, or came from a bad batch.

If you are simply sending these as an email it might be an alternative to not store the pictures on your hard-drive at all. Or you could add an USB hard-drive or memory stick and use that to store the pictures.

You could also cache the pictures and write out a couple at a time instead of writing each one out directly to reduce the load on the SD card. This would be as simple as storing let’s say five pictures in memory, and once you have taken five pictures, write them out.

pictures = {}
pictures[get_timestamp] = image_output

Then once you have reached a total of five entries you loop through them, use the key to generate the file-name while the value contains the actual picture. You then save all five on your hard-drive.

If you have the 512 MB version you could increase the number of pictures stored in memory, but keep in mind that in case of a power failure you would lose anything in memory.

于 2013-05-04T00:16:53.700 回答