RTC驅(qū)動(dòng)分析

學(xué)號(hào):19021211263

linux中的rtc驅(qū)動(dòng)位于drivers/rtc下,里面包含了許多開(kāi)發(fā)平臺(tái)的RTC驅(qū)動(dòng)荤崇,我們這里是以S3C24xx為主,所以它的RTC驅(qū)動(dòng)為rtc-s3c.c

1削饵、入口函數(shù)s3c_rtc_init分析

進(jìn)入./drivers/rtc/rtc-s3c.c诀豁,找到入口函數(shù),如下所示:

static struct platform_driver s3c2410_rtcdrv = {
    .probe      = s3c_rtc_probe,//.probe函數(shù)
    .remove     = s3c_rtc_remove,
    .suspend    = s3c_rtc_suspend,
    .resume     = s3c_rtc_resume,
    .driver     = {
        .name   = "s3c2410-rtc",
        .owner  = THIS_MODULE,
    },
};

static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics\n";

static int __init s3c_rtc_init(void)
{
    printk(banner);
    return platform_driver_register(&s3c2410_rtcdrv);
}

module_init(s3c_rtc_init);

這里注冊(cè)了一個(gè)“s3c2410-rtc”名稱(chēng)的平臺(tái)設(shè)備驅(qū)動(dòng)

而“s3c2410-rtc”的平臺(tái)設(shè)備,在./arch/arm/plat-s3c24xx/devs.c里定義了,只不過(guò)這里沒(méi)有注冊(cè),如下所示:

/* RTC */

static struct resource s3c_rtc_resource[] = {
    [0] = {
        .start = S3C24XX_PA_RTC,//RTC寄存器地址
        .end   = S3C24XX_PA_RTC + 0xff,
        .flags = IORESOURCE_MEM,//內(nèi)存資源
    },
    [1] = {
        .start = IRQ_RTC,//RTC鬧鐘中斷
        .end   = IRQ_RTC,
        .flags = IORESOURCE_IRQ,//IRQ資源
    },
    [2] = {
        .start = IRQ_TICK,//RTC時(shí)鐘節(jié)拍中斷
        .end   = IRQ_TICK,
        .flags = IORESOURCE_IRQ//IRQ資源
    }
};

struct platform_device s3c_device_rtc = {
    .name         = "s3c2410-rtc",
    .id       = -1,
    .num_resources    = ARRAY_SIZE(s3c_rtc_resource),
    .resource     = s3c_rtc_resource,
};

EXPORT_SYMBOL(s3c_device_rtc);

當(dāng)內(nèi)核匹配到有與它名稱(chēng)同名的平臺(tái)設(shè)備,就會(huì)調(diào)用.probe函數(shù),接下來(lái)我們便進(jìn)入s3c2410_rtcdrv->probe函數(shù)(即s3c_rtc_probe函數(shù))中看看,做了什么:

static int s3c_rtc_probe(struct platform_device *pdev)
{
    struct rtc_device *rtc;           //rtc設(shè)備結(jié)構(gòu)體
    struct resource *res;
    int ret;

    s3c_rtc_tickno = platform_get_irq(pdev, 1);//獲取IRQ_TICK節(jié)拍中斷資源
    s3c_rtc_alarmno = platform_get_irq(pdev, 0);//獲取IRQ_RTC鬧鐘中斷資源
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);//獲取內(nèi)存資源

    s3c_rtc_mem = request_mem_region(res->start,res->end-res->start+1,pdev->name);//申請(qǐng)內(nèi)存資源

    s3c_rtc_base = ioremap(res->start, res->end - res->start + 1);//對(duì)內(nèi)存進(jìn)行重映射

    s3c_rtc_enable(pdev, 1);//設(shè)置硬件相關(guān)設(shè)置,使能RTC寄存器

    s3c_rtc_setfreq(s3c_rtc_freq);//設(shè)置TICONT寄存器辜窑,使能節(jié)拍中斷,設(shè)置節(jié)拍計(jì)數(shù)值

    /*1.注冊(cè)RTC設(shè)備*/
    rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,THIS_MODULE);

    rtc->max_user_freq = 128;
    platform_set_drvdata(pdev, rtc);
    return 0;
}

顯然最終會(huì)調(diào)用rtc_device_register()函數(shù)來(lái)向內(nèi)核注冊(cè)rtc_device設(shè)備,注冊(cè)成功會(huì)返回一個(gè)已注冊(cè)好的rtc_device,而s3c_rtcops是一個(gè)rtc_class_ops結(jié)構(gòu)體,里面就是保存如何操作這個(gè)rtc設(shè)備的函數(shù),比如讀寫(xiě)RTC時(shí)間,讀寫(xiě)鬧鐘時(shí)間等,注冊(cè)后,會(huì)保存在rtc_device->ops里躺盛。

rtc_device_register()函數(shù)在drivers/rtc/Class.c文件內(nèi)被定義。Class.c文件主要定義了RTC子系統(tǒng),而內(nèi)核初始化,便會(huì)進(jìn)入Class.c彩库。


再?gòu)腃lass.c中的初始化函數(shù)看:

先進(jìn)入rtc_init()在創(chuàng)建了相關(guān)的類(lèi)之后會(huì)調(diào)用rtc_dev_init()肤无,在rtc_dev_init()中會(huì)通過(guò)alloc_chrdev_region()函數(shù)來(lái)注冊(cè)字符設(shè)備:

err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc");// RTC_DEV_MAX=16,表示只注冊(cè)0~15個(gè)次設(shè)備號(hào),設(shè)備編號(hào)保存在rtc_devt中 

2、rtc_device_register()函數(shù)分析

Class.c中的alloc_chrdev_region()函數(shù)和./arch/arm/plat-s3c24xx/devs.c中通過(guò)rtc_device_register()函數(shù)注冊(cè)RTC設(shè)備,會(huì)有什么關(guān)系骇钦?

接下來(lái)便來(lái)看rtc_device_register(),代碼如下:

struct rtc_device *rtc_device_register(const char *name, struct device *dev,const struct rtc_class_ops *ops,struct module *owner)
{
    struct rtc_device *rtc;//定義一個(gè)rtc_device結(jié)構(gòu)體
    ... ...
    rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);      //分配rtc_device結(jié)構(gòu)體為全局變量


    /*設(shè)置rtc_device*/
    rtc->id = id;
    rtc->ops = ops;//將s3c_rtcops保存在rtc_device->ops里
    rtc->owner = owner;
    rtc->max_user_freq = 64;
    rtc->dev.parent = dev;
    rtc->dev.class = rtc_class;
    rtc->dev.release = rtc_device_release;
    ... ...

    rtc_dev_prepare(rtc);   //1.做提前準(zhǔn)備,初始化cdev結(jié)構(gòu)體
    ... ...
    rtc_dev_add_device(rtc);//2.在/dev下創(chuàng)建rtc相關(guān)文件,將cdev添加到系統(tǒng)中

    rtc_sysfs_add_device(rtc);//在/sysfs下創(chuàng)建rtc相關(guān)文件
    rtc_proc_add_device(rtc); //在/proc下創(chuàng)建rtc相關(guān)文件
    ... ...
    return rtc;
}

上面的rtc_dev_prepare(rtc)和rtc_dev_add_device(rtc)主要做了以下兩件事(位于./drivers/rtc/rtc-dev.c):

  • rtc_dev_prepare(rtc)中:

    cdev_init(&rtc->char_dev, &rtc_dev_fops);//綁定file_operations  
    
  • rtc_dev_add_device(rtc)中:

    cdev_add(&rtc->char_dev, rtc->dev.devt, 1);//注冊(cè)rtc->char_dev字符設(shè)備,添加一個(gè)從設(shè)備到系統(tǒng)中
    

顯然這里就是利用新方法注冊(cè)字符設(shè)備


.probe函數(shù)總結(jié)

所以“s3c2410-rtc”平臺(tái)設(shè)備驅(qū)動(dòng)的.probe主要做了以下幾件事:

  • 1.設(shè)置RTC相關(guān)寄存器

  • 2.分配rtc_device結(jié)構(gòu)體

  • 3.設(shè)置rtc_device結(jié)構(gòu)體

    • 3.1 通過(guò)rtc_device_register函數(shù)宛渐,將struct rtc_class_ops s3c_rtcops放入rtc_device->ops,實(shí)現(xiàn)對(duì)RTC讀寫(xiě)時(shí)間等操作
  • 4.注冊(cè)rtc->char_dev字符設(shè)備眯搭,通過(guò)cdev_init函數(shù)將該字符設(shè)備的操作結(jié)構(gòu)體設(shè)為:struct file_operations rtc_dev_fops


3窥翩、file_operations結(jié)構(gòu)體分析

綜上所述,rtc->char_dev字符設(shè)備中綁定的file_operations結(jié)構(gòu)體rtc_dev_fops為:

static const struct file_operations rtc_dev_fops = {
    .owner      = THIS_MODULE,
    .llseek     = no_llseek,
    .read       = rtc_dev_read,
    .poll       = rtc_dev_poll,
    .ioctl      = rtc_dev_ioctl,
    .open       = rtc_dev_open,
    .release    = rtc_dev_release,
    .fasync     = rtc_dev_fasync,
};

3.1鳞仙、open函數(shù)

當(dāng)應(yīng)用層open(”/dev/rtcXX”)時(shí),就會(huì)調(diào)用rtc_dev_fops->rtc_dev_open(),我們來(lái)看看如何open的:

static int rtc_dev_open(struct inode *inode, struct file *file)
{
    struct rtc_device *rtc = container_of(inode->i_cdev,struct rtc_device, char_dev);//獲取對(duì)應(yīng)的rtc_device結(jié)構(gòu)體
    const struct rtc_class_ops *ops = rtc->ops;//最終等于s3c_rtcops

    file->private_data = rtc;//設(shè)置file結(jié)構(gòu)體的私有成員等于rtc_device,再次執(zhí)行ioctl等函數(shù)時(shí),直接就可以提取file->private_data即可

    err = ops->open ? ops->open(rtc->dev.parent) : 0;//調(diào)用s3c_rtcops->open

    mutex_unlock(&rtc->char_lock);
    return err;
}

container_of:

#define container_of(ptr, type, member) ({              \         
const typeof( ((type *)0)->member ) *__mptr = (ptr);    \         
(type *)( (char *)__mptr - offsetof(type,member) );})
//ptr:返回的type類(lèi)型的結(jié)構(gòu)體首地址
//type:該結(jié)構(gòu)體類(lèi)型
//member:結(jié)構(gòu)體中的某一個(gè)成員

通過(guò)一個(gè)結(jié)構(gòu)變量中一個(gè)成員的地址member找到這個(gè)結(jié)構(gòu)體變量的首地址ptr寇蚊。

顯然最終還是調(diào)用rtc_device下的s3c_rtcops->open函數(shù):

static const struct rtc_class_ops s3c_rtcops = {
    .open       = s3c_rtc_open,
    .release    = s3c_rtc_release,
    .ioctl      = s3c_rtc_ioctl,
    .read_time  = s3c_rtc_gettime,
    .set_time   = s3c_rtc_settime,
    .read_alarm = s3c_rtc_getalarm,
    .set_alarm  = s3c_rtc_setalarm,
    .proc           = s3c_rtc_proc,
};

s3c_rtc_open()函數(shù),而s3c_rtc_open()函數(shù)里主要是申請(qǐng)了兩個(gè)中斷棍好,一個(gè)鬧鐘中斷仗岸,一個(gè)計(jì)時(shí)中斷:

static int s3c_rtc_open(struct device *dev)
{     
    struct platform_device *pdev = to_platform_device(dev);    
    struct rtc_device *rtc_dev = platform_get_drvdata(pdev);      
    int ret;

    ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq,IRQF_DISABLED,  "s3c2410-rtc alarm", rtc_dev);//申請(qǐng)鬧鐘中斷                      
    if (ret) {
        dev_err(dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret);
        return ret;
    }

    
    ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq,IRQF_DISABLED,  "s3c2410-rtc tick", rtc_dev);//申請(qǐng)計(jì)時(shí)中斷   
    if (ret) {
        dev_err(dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);
        goto tick_err;
    }

    return ret;

    tick_err:
    free_irq(s3c_rtc_alarmno, rtc_dev);
    return ret;
}

3.2、ioctl函數(shù)

當(dāng)我們應(yīng)用層open后借笙,使用 ioctl(int fd, unsigned long cmd, ...)時(shí)扒怖,就會(huì)調(diào)用rtc_dev_fops-> rtc_dev_ioctl ():

static int rtc_dev_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)
{
    struct rtc_device *rtc = file->private_data;//提取rtc_device
    void __user *uarg = (void __user *) arg;
    ... ...

    switch (cmd) {
        case RTC_EPOCH_SET:
        case RTC_SET_TIME://設(shè)置時(shí)間
            if (!capable(CAP_SYS_TIME))
                return -EACCES;
            break;
        case RTC_IRQP_SET://改變中斷觸發(fā)速度
            ... ...
    ... ...}

    switch (cmd) {
        case RTC_ALM_READ://讀鬧鐘時(shí)間
            err = rtc_read_alarm(rtc, &alarm);//調(diào)用s3c_rtcops-> read_alarm
            if (err < 0)
                return err;

            if (copy_to_user(uarg, &alarm.time, sizeof(tm)))//長(zhǎng)傳時(shí)間數(shù)據(jù)
                return -EFAULT;
            break;

        case RTC_ALM_SET://設(shè)置鬧鐘時(shí)間 , 調(diào)用s3c_rtcops-> set_alarm
            ... ...

        case RTC_RD_TIME://讀RTC時(shí)間, 調(diào)用s3c_rtcops-> read_alarm
            err = rtc_read_time(rtc, &tm);
            ... ...

        case RTC_SET_TIME://寫(xiě)RTC時(shí)間,調(diào)用s3c_rtcops-> set_time
            ... ...

        case RTC_IRQP_SET://改變中斷觸發(fā)頻率,調(diào)用s3c_rtcops-> irq_set_freq
            ... ...
    }

這里我們假設(shè)是讀RTC時(shí)間,即會(huì)進(jìn)入rtc_read_time函數(shù):

int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
{
    int err;

    err = mutex_lock_interruptible(&rtc->ops_lock);
    if (err)
        return -EBUSY;

    if (!rtc->ops)
        err = -ENODEV;
    else if (!rtc->ops->read_time)
        err = -EINVAL;
    else {
        memset(tm, 0, sizeof(struct rtc_time));
        err = rtc->ops->read_time(rtc->dev.parent, tm);//最終調(diào)用該函數(shù)
    }

    mutex_unlock(&rtc->ops_lock);
    return err;
}

從上面可以看出业稼,rtc->ops->read_time即為rtc_device結(jié)構(gòu)體下的ops成員s3c_rtcops下的read_time函數(shù)姚垃,即s3c_rtc_getalarm函數(shù)

調(diào)用了半天,最終還是調(diào)用s3c_rtcops下的成員函數(shù)

繼續(xù)分析s3c_rtc_getalarm函數(shù)盼忌,看看如何讀出時(shí)間:

static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
{
    unsigned int have_retried = 0;
    void __iomem *base = s3c_rtc_base;//獲取RTC相關(guān)寄存器基地址


retry_get_time:

    /*獲取年,月,日,時(shí),分,秒寄存器*/
    rtc_tm->tm_min  = readb(base + S3C2410_RTCMIN);     
    rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR);
    rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE);
    rtc_tm->tm_mon  = readb(base + S3C2410_RTCMON);
    rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR);
    rtc_tm->tm_sec  = readb(base + S3C2410_RTCSEC);


    /*  判斷秒寄存器中是0积糯,則表示過(guò)去了一分鐘,那么小時(shí)谦纱,天看成,月,等寄存器中的值都可能已經(jīng)變化跨嘉,需要重新讀取這些寄存器的值*/
    if (rtc_tm->tm_sec == 0 && !have_retried) {
        have_retried = 1;
        goto retry_get_time;
    }

    /*將獲取的寄存器值,轉(zhuǎn)換為真正的時(shí)間數(shù)據(jù)*/
    BCD_TO_BIN(rtc_tm->tm_sec);
    BCD_TO_BIN(rtc_tm->tm_min);
    BCD_TO_BIN(rtc_tm->tm_hour);
    BCD_TO_BIN(rtc_tm->tm_mday);
    BCD_TO_BIN(rtc_tm->tm_mon);
    BCD_TO_BIN(rtc_tm->tm_year);

    rtc_tm->tm_year += 100;//存儲(chǔ)器中存放的是從1900年開(kāi)始的時(shí)間川慌,所以加上100 
    rtc_tm->tm_mon -= 1;
    return 0;
}

同樣, 在s3c_rtc_gettime函數(shù)下(即s3c_rtcops-> set_time()函數(shù)),也是向相關(guān)寄存器寫(xiě)入RTC時(shí)間


總結(jié)

  • rtc_device->char_dev :字符設(shè)備,與應(yīng)用層、以及更底層的函數(shù)打交道
  • rtc_device->ops   ∶沃亍:更底層的操作函數(shù)兑燥,直接操作硬件相關(guān)的寄存器,被rtc_device->char_dev調(diào)用

4琴拧、修改內(nèi)核

我們單板上使用ls /dev/rtc*,找不到該字符設(shè)備, 因?yàn)閮?nèi)核里只定義了s3c_device_rtc這個(gè)RTC平臺(tái)設(shè)備,沒(méi)有注冊(cè),所以平臺(tái)驅(qū)動(dòng)沒(méi)有被匹配上,接下來(lái)我們來(lái)修改內(nèi)核里的注冊(cè)數(shù)組

4.1進(jìn)入arch/arm/plat-s3c24xx/Common-smdk.c

如下所示,在smdk_devs[]里,添加RTC的平臺(tái)設(shè)備即可,當(dāng)內(nèi)核啟動(dòng)時(shí),就會(huì)調(diào)用該數(shù)組,將里面的platform_device統(tǒng)統(tǒng)注冊(cè)一遍


static struct platform_device __initdata *smdk_devs[] = {
    &s3c_device_nand,
    &smdk_led4,
    &smdk_led5,
    &smdk_led6,
    &smdk_led7,
    &s3c_device_rtc,//加入這一行
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
    &s3c_device_dm9k,
#endif    
#ifdef CONFIG_SERIAL_EXTEND_S3C24xx
    &s3c_device_8250,
#endif
#ifdef CONFIG_TOUCHSCREEN_S3C2410
    &s3c_device_ts,
#endif
};

然后將Common-smdk.c代替虛擬機(jī)的內(nèi)核目錄下的Common-smdk.c,重新make uImage編譯內(nèi)核即可

5降瞳、測(cè)試運(yùn)行

啟動(dòng)后,如下所示, 使用ls /dev/rtc*,就找到了rtc0這個(gè)字符設(shè)備

# ls /dev/rtc*
/dev/rtc0
#

5.1、設(shè)置RTC時(shí)間

在linux里有兩個(gè)時(shí)鐘:

硬件時(shí)鐘(2440里寄存器的時(shí)鐘)蚓胸、系統(tǒng)時(shí)鐘(內(nèi)核中的時(shí)鐘)

所以有兩個(gè)不同的命令: date命令挣饥、hwclock命令

5.2、date命令

輸入date查看系統(tǒng)時(shí)鐘:

# date
wed Nov  3 14:50:24 UTC 2021

如果覺(jué)得不方便也可以指定格式顯示日期沛膳,需要在字符串前面加”+”

如下所示,輸入了 date "+ %Y/%m/%d %H:%M:%S"

# date
wed Nov 3 14:54:30 UTC 2021
#
#
# data "+ %Y/%m/%d %H:%M:%S"
 2021/11/03 14:54:33
  • %M:表示秒
  • %m:表示月
  • %Y:表示年,當(dāng)只需要最后兩位數(shù)字,輸入%y即可

date命令設(shè)置時(shí)間格式如下:

date 月日時(shí)分年.秒

如下所示,輸入date 111515292017.20扔枫,即可設(shè)置好系統(tǒng)時(shí)鐘

# date 111515292017.20
wed Nov 15 15:29:20 UTC 2017
#

5.3、hwclock命令

常用參數(shù)如下所示

  • -r, --show 讀取并打印硬件時(shí)鐘(read hardware clock and print result )
  • -s, --hctosys 將硬件時(shí)鐘同步到系統(tǒng)時(shí)鐘(set the system time from the hardware clock )
  • -w, --systohc 將系統(tǒng)時(shí)鐘同步到硬件時(shí)鐘(set the hardware clock to the current system time )

如下所示,使用hwclock -w锹安,即可同步硬件時(shí)鐘

# hwclock -r
Wed Nov  3 15:20:46 2021 0.000000 seconds 未同步之前的時(shí)間
# hwclock -w
# hwclock -r
Wed Nov 15 15:30:06 2017 0.000000 seconds 同步后的時(shí)間
#

然后重啟后,使用date命令,看到時(shí)間正常

更多有趣內(nèi)容歡迎訪問(wèn)我的個(gè)人博客短荐。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市叹哭,隨后出現(xiàn)的幾起案子忍宋,更是在濱河造成了極大的恐慌,老刑警劉巖话速,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異芯侥,居然都是意外死亡泊交,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)柱查,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)廓俭,“玉大人,你說(shuō)我怎么就攤上這事唉工⊙衅梗” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵淋硝,是天一觀的道長(zhǎng)雹熬。 經(jīng)常有香客問(wèn)我,道長(zhǎng)谣膳,這世上最難降的妖魔是什么竿报? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮继谚,結(jié)果婚禮上烈菌,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好芽世,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布挚赊。 她就那樣靜靜地躺著,像睡著了一般济瓢。 火紅的嫁衣襯著肌膚如雪荠割。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天葬荷,我揣著相機(jī)與錄音涨共,去河邊找鬼。 笑死宠漩,一個(gè)胖子當(dāng)著我的面吹牛举反,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扒吁,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼火鼻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了雕崩?” 一聲冷哼從身側(cè)響起魁索,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盼铁,沒(méi)想到半個(gè)月后粗蔚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饶火,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年鹏控,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肤寝。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡当辐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鲤看,到底是詐尸還是另有隱情缘揪,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布义桂,位于F島的核電站,受9級(jí)特大地震影響慷吊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜罢浇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一沐祷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧攒岛,春花似錦赖临、人聲如沸灾锯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)吵聪。三九已至,卻和暖如春兼雄,著一層夾襖步出監(jiān)牢的瞬間吟逝,已是汗流浹背赦肋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佃乘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓庞呕,卻偏偏與公主長(zhǎng)得像程帕,于是被迫代替她去往敵國(guó)和親住练。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骆捧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容