openharmony:bootstrap服务启动引导组件

kernel:litoes_m
MCU:stm32f407zgt6

本文只讲解bootstrap组件的移植。bootstrap组件的原理介绍请移步官网文档.

简介

bootstrap服务启动组件实现了服务的自动初始化,即服务的初始化函数无需显式调用,而是将其使用宏定义的方式申明,就会在系统启动时自动被执行。实现原理是将服务启动的函数通过宏定义的方式申明之后,放在预定义好的zInit代码段中,系统启动的时候调用OHOS_SystemInit接口遍历该代码段并调用其中的函数。因此,需要在链接脚本中添加zInit段,并且在main函数里调用OHOS_SystemInit接口。

目录

base/startup/bootstrap_lite/    # 启动引导组件
└── services
    └── source               # 启动引导组件源文件目录

约束

目前支持轻量系统设备(参考内存≥128KB),如Hi3861V100。

使用说明

bootstrap组件无需单独配置,在SAMGR启动时会自动调用,用于启动系统服务。

移植过程

1. STM32F407ZGTx_FLASH.ld

在连接脚本中增加zInit代码段

  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    /* bootstrap中增加的内容 - 开始 */
    __zinitcall_bsp_start = .;
    KEEP (*(.zinitcall.bsp0.init))
    KEEP (*(.zinitcall.bsp1.init))
    KEEP (*(.zinitcall.bsp2.init))
    KEEP (*(.zinitcall.bsp3.init))
    KEEP (*(.zinitcall.bsp4.init))
    __zinitcall_bsp_end = .;
    __zinitcall_device_start = .;
    KEEP (*(.zinitcall.device0.init))
    KEEP (*(.zinitcall.device1.init))
    KEEP (*(.zinitcall.device2.init))
    KEEP (*(.zinitcall.device3.init))
    KEEP (*(.zinitcall.device4.init))
    __zinitcall_device_end = .;
    __zinitcall_core_start = .;
    KEEP (*(.zinitcall.core0.init))
    KEEP (*(.zinitcall.core1.init))
    KEEP (*(.zinitcall.core2.init))
    KEEP (*(.zinitcall.core3.init))
    KEEP (*(.zinitcall.core4.init))
    __zinitcall_core_end = .;
    __zinitcall_sys_service_start = .;
    KEEP (*(.zinitcall.sys.service0.init))
    KEEP (*(.zinitcall.sys.service1.init))
    KEEP (*(.zinitcall.sys.service2.init))
    KEEP (*(.zinitcall.sys.service3.init))
    KEEP (*(.zinitcall.sys.service4.init))
    __zinitcall_sys_service_end = .;
    __zinitcall_sys_feature_start = .;
    KEEP (*(.zinitcall.sys.feature0.init))
    KEEP (*(.zinitcall.sys.feature1.init))
    KEEP (*(.zinitcall.sys.feature2.init))
    KEEP (*(.zinitcall.sys.feature3.init))
    KEEP (*(.zinitcall.sys.feature4.init))
    __zinitcall_sys_feature_end = .;
    __zinitcall_run_start = .;
    KEEP (*(.zinitcall.run0.init))
    KEEP (*(.zinitcall.run1.init))
    KEEP (*(.zinitcall.run2.init))
    KEEP (*(.zinitcall.run3.init))
    KEEP (*(.zinitcall.run4.init))
    __zinitcall_run_end = .;
    __zinitcall_app_service_start = .;
    KEEP (*(.zinitcall.app.service0.init))
    KEEP (*(.zinitcall.app.service1.init))
    KEEP (*(.zinitcall.app.service2.init))
    KEEP (*(.zinitcall.app.service3.init))
    KEEP (*(.zinitcall.app.service4.init))
    __zinitcall_app_service_end = .;
    __zinitcall_app_feature_start = .;
    KEEP (*(.zinitcall.app.feature0.init))
    KEEP (*(.zinitcall.app.feature1.init))
    KEEP (*(.zinitcall.app.feature2.init))
    KEEP (*(.zinitcall.app.feature3.init))
    KEEP (*(.zinitcall.app.feature4.init))
    __zinitcall_app_feature_end = .;
    __zinitcall_test_start = .;
    KEEP (*(.zinitcall.test0.init))
    KEEP (*(.zinitcall.test1.init))
    KEEP (*(.zinitcall.test2.init))
    KEEP (*(.zinitcall.test3.init))
    KEEP (*(.zinitcall.test4.init))
    __zinitcall_test_end = .;
    __zinitcall_exit_start = .;
    KEEP (*(.zinitcall.exit0.init))
    KEEP (*(.zinitcall.exit1.init))
    KEEP (*(.zinitcall.exit2.init))
    KEEP (*(.zinitcall.exit3.init))
    KEEP (*(.zinitcall.exit4.init))
    __zinitcall_exit_end = .;
    /* bootstrap中增加的内容 - 结束 */

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

2. vendor/fx/TunnelControl/config.json下增加组件

//vendor/fx/TunnelControl/config.json
        {
            "subsystem": "startup",
            "components": [
                {
                    "component": "bootstrap_lite"
                }
            ]
        },

组件bootstrap的初始化接口函数base/startup/bootstrap_lite/services/source/system_init.c中的OHOS_SystemInit()中调用函数SAMGR_Bootstrap()

void OHOS_SystemInit(void)
{
    MODULE_INIT(bsp);
    MODULE_INIT(device);
    MODULE_INIT(core);
    SYS_INIT(service);
    SYS_INIT(feature);
    MODULE_INIT(run);
    SAMGR_Bootstrap();
}

hb build之后会继续,会报如下错误:

[OHOS ERROR] system_init.c:(.text.OHOS_SystemInit+0x6e): undefined reference to `SAMGR_Bootstrap'
[OHOS ERROR] collect2: error: ld returned 1 exit status

vendor/fx/tunnel/config.json下需要加入组件samgr_lite

        {
            "subsystem": "distributedschedule",
            "components": [
              {
                "component": "samgr_lite",
                "features": []
              }
            ]
        },

hb build之后会继续,会报如下错误:

[OHOS ERROR] samgr_lite.c:(.text.AddTaskPool+0x62): undefined reference to `HiLogPrintf'

vendor/fx/TunnelControl/config.json下需要加入组件hilog_lite

        {
            "subsystem": "hiviewdfx",
            "components": [
              {
                "component": "hilog_lite",
                "features": []
              }
            ]
        },

hb build之后会继续,会报如下错误:

[OHOS ERROR] In file included from ../../../base/hiviewdfx/hiview_lite/hiview_file.c:16:
[OHOS ERROR] ../../../base/hiviewdfx/hiview_lite/hiview_config.h:21:10: fatal error: ohos_types.h: No such file or directory
[OHOS ERROR]    21 | #include "ohos_types.h"

找到ohos_types.h路径,将ohos_types.h的路径加入device/board/fx/bajie/liteos_m/config.gni中。如下所示:

//device/board/fx/bajie/liteos_m/config.gni
board_include_dirs = [
    "//utils/native/lite/include"
]

hb build之后会继续,会报如下错误:

[OHOS ERROR] hiview_util.c:(.text.HIVIEW_GetCurrentTime+0x1c): undefined reference to `clock_gettime'
[OHOS ERROR] collect2: error: ld returned 1 exit status

函数clock_gettimekernel/liteos_m/kal/posix/src/time.c中。从posix可以看出,需要使能posix接口。make menuconfig选择如下:

[*] Enable KAL CMSIS (NEW)
    Choose libc implementation (newlibc)  --->
[*] Enable POSIX API
[*]     Enable POSIX Thread API (NEW)
[*]     Enable POSIX Semaphore API (NEW)
[*]     Enable POSIX Clock API (NEW)
[*]     Enable POSIX Mqueue API (NEW)
[*]     Enable POSIX Pipe API (NEW)
[*]     Enable POSIX Signal API (NEW)

此时hb build不报错。

[OHOS INFO] ---------------------------------------------
[OHOS INFO] c targets overlap rate statistics
[OHOS INFO] subsystem           files NO.       percentage      builds NO.      percentage      overlap rate
[OHOS INFO] distributedschedule       15        6.1%          15        6.1%    1.00
[OHOS INFO] hiviewdfx                 10        4.0%          10        4.0%    1.00
[OHOS INFO] kernel                    51        20.6%         51        20.6%   1.00
[OHOS INFO] securec                   39        15.8%         39        15.8%   1.00
[OHOS INFO] startup                    2        0.8%           2        0.8%    1.00
[OHOS INFO] test                       2        0.8%           2        0.8%    1.00
[OHOS INFO] third_party              127        51.4%        127        51.4%   1.00
[OHOS INFO] xts                        2        0.8%           2        0.8%    1.00
[OHOS INFO] 
[OHOS INFO] c overall build overlap rate: 1.00
[OHOS INFO] 
[OHOS INFO] 
[OHOS INFO] tunnel build success
[OHOS INFO] cost time: 0:00:08

可以看出,子系统startuphiviewdfxdistributedschedule都被编译成功。

3.编写测试代码

在main.c中编程测试代码,测试startup功能。

//增加一下两个头文件
#include "ohos_init.h"
#include "ohos_types.h"
……
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    HAL_Delay(3000);
    usart_printf_init();
    PRINT_INFO("SCB->VTOR = 0x%08lX\r\n", SCB->VTOR);
    UINT32 ret;
    ret = LOS_KernelInit();
    OHOS_SystemInit();    // 这句式必须增加的,该接口遍历zInit代码段并调用其中的函数。
    if (ret == LOS_OK)
    {
        LOS_Start();
    }

    while (1)
    {
        __asm volatile("wfi");
    }
}

运行时报如下错误:

*************Exception Information**************
Type      = 11
ThrdPid   = 25
Phase     = exc in task
FaultAddr = 0xabababab
Current task info:
Task name = 
Task ID   = 25
Task SP   = 00000000
Task ST   = 0x0
Task SS   = 0x0
Exception reg dump:
PC        = 0x80155e2
LR        = 0x8015823
SP        = 0x2001ffb8
R0        = 0x0
R1        = 0x8023a38
R2        = 0x0
R3        = 0x20011de0
R4        = 0x0
R5        = 0x8023a38
R6        = 0x0
R7        = 0x2001fff0
R8        = 0x0
R9        = 0x0
R10       = 0x0
R11       = 0x0
R12       = 0x0
PriMask   = 0x0
xPSR      = 0x41000000
----- backtrace start -----
backtrace 0 -- lr = 0x8015822
backtrace 1 -- lr = 0x8013314
backtrace 2 -- lr = 0x8011998
backtrace 3 -- lr = 0x80123b6
----- backtrace end -----

 TID  Priority   Status StackSize WaterLine StackPoint TopOfStack EventMask  SemID  TaskEntry name
 ---  -------- -------- --------- --------- ---------- ---------- --------- ------ ---------- ----
   0        0     Ready     0x2d0      0xcc 0x20004614 0x20004410         0 0xffff 0x800ea41 Swt_Task                        
   1       31     Ready     0x500      0xcc 0x20004b24 0x200046f0         0 0xffff 0x800ef15 IdleCore000  

从图中可以看出PC= 0x80155e2。在.asm文件中查到搜索80155e2,定位到出现问题的代码位置。考虑到cortex-m采用的是三级流水线技术。实际当前运行位置应该是80155e8。

080155c8 <HiLogRegisterModule>:
 80155c8:   b570        push    {r4, r5, r6, lr}
 80155ca:   b082        sub sp, #8
 80155cc:   4604        mov r4, r0
 80155ce:   460d        mov r5, r1
 80155d0:   4b2b        ldr r3, [pc, #172]  ; (8015680 <HiLogRegisterModule+0xb8>)
 80155d2:   681b        ldr r3, [r3, #0]
 80155d4:   9301        str r3, [sp, #4]
 80155d6:   f04f 0300   mov.w   r3, #0
 80155da:   eb00 0280   add.w   r2, r0, r0, lsl #2
 80155de:   4b29        ldr r3, [pc, #164]  ; (8015684 <HiLogRegisterModule+0xbc>)
 80155e0:   4413        add r3, r2
 80155e2:   f8d3 2001   ldr.w   r2, [r3, #1]
 80155e6:   4601        mov r1, r0
 80155e8:   4827        ldr r0, [pc, #156]  ; (8015688 <HiLogRegisterModule+0xc0>)
 80155ea:   f7fc f8d7   bl  801179c <__wrap_printf>
 80155ee:   2c3f        cmp r4, #63 ; 0x3f
 80155f0:   d840        bhi.n   8015674 <HiLogRegisterModule+0xac>
 80155f2:   2d00        cmp r5, #0
 80155f4:   d040        beq.n   8015678 <HiLogRegisterModule+0xb0>
 80155f6:   eb04 0284   add.w   r2, r4, r4, lsl #2
 80155fa:   4b22        ldr r3, [pc, #136]  ; (8015684 <HiLogRegisterModule+0xbc>)
 80155fc:   4413        add r3, r2
 80155fe:   f8d3 3001   ldr.w   r3, [r3, #1]
 8015602:   b14b        cbz r3, 8015618 <HiLogRegisterModule+0x50>
 8015604:   2000        movs    r0, #0
 8015606:   4b1e        ldr r3, [pc, #120]  ; (8015680 <HiLogRegisterModule+0xb8>)
 8015608:   681a        ldr r2, [r3, #0]
 801560a:   9b01        ldr r3, [sp, #4]

异常发生在一个名为base/hiviewdfx/hilog_lite/frameworks/mini/hiview_log.c中的函数HiLogRegisterModule。分析问题的过程就不说了。问题出现在结构体HiLogModuleInfo上。代码中强制1字节对齐。cortex-m的地址是4字节的,必须4字节对齐。

base/hiviewdfx/hiview_lite/hiview_def.h

#pragma pack(1)  此处的pack(1)->pack(4)
typedef struct {
    uint8 id;
    const char *name; /* LOG_MODULE_NAME_LEN */
} HiLogModuleInfo;
#pragma pack()

hb build之后,下载运行后,报如下错误:

*************Exception Information**************
Type      = 11
ThrdPid   = 25
Phase     = exc in task
FaultAddr = 0xabababab
Current task info:
Task name = 
Task ID   = 25
Task SP   = 00000000
Task ST   = 0x0
Task SS   = 0x0
Exception reg dump:
PC        = 0x80156e0
LR        = 0x80156dd
SP        = 0x2001ff88
R0        = 0x1
R1        = 0x1
R2        = 0x20000534
R3        = 0x0
R4        = 0x1
R5        = 0x0
R6        = 0x1
R7        = 0x80239b8
R8        = 0x0
R9        = 0x0
R10       = 0x0
R11       = 0x0
R12       = 0x6
PriMask   = 0x0
xPSR      = 0x41000000
----- backtrace start -----
backtrace 0 -- lr = 0x80158a2
backtrace 1 -- lr = 0x8013314
backtrace 2 -- lr = 0x8011998
backtrace 3 -- lr = 0x80123b6
----- backtrace end -----

 TID  Priority   Status StackSize WaterLine StackPoint TopOfStack EventMask  SemID  TaskEntry name
 ---  -------- -------- --------- --------- ---------- ---------- --------- ------ ---------- ----
   0        0     Ready     0x2d0      0xcc 0x20004614 0x20004410         0 0xffff 0x800ea41 Swt_Task                        
   1       31     Ready     0x500      0xcc 0x20004b24 0x200046f0         0 0xffff 0x800ef15 IdleCore000       

根据PC=0x80156e0,在.asm文件中找到出问题的函数HiLogPrintf()。找到其中的结构体,查看一下是否又pack(1)了。

base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite/hiview_log.h

#pragma pack(1) 改成 pack(4)
typedef struct {
    uint8 head;
    uint8 module;
    uint8 level : 4;
    uint8 valueNumber : 4;
    uint8 task;
    uint32 time; /* seconds */
    uint16 milli; /* millisecond, 0-999 */
    const char *fmt;
} HiLogCommon;

typedef struct {
    HiLogCommon commonContent;
    uint32 values[LOG_MULTI_PARA_MAX];
} HiLogContent;
#pragma pack()

之后遇到的几个问题都是用于pack(1)导致的。都改完之后,系统可以运行就起作用了。

然后可以调用utils/native/lite/include/ohos_init.h提供的api了。

#define CORE_INIT(func) LAYER_INITCALL_DEF(func, core, "core")
#define CORE_INIT_PRI(func, priority) LAYER_INITCALL(func, core, "core", priority)
#define SYS_SERVICE_INIT(func) LAYER_INITCALL_DEF(func, sys_service, "sys.service")
#define SYS_SERVICE_INIT_PRI(func, priority) LAYER_INITCALL(func, sys_service, "sys.service", priority)
#define SYS_FEATURE_INIT(func) LAYER_INITCALL_DEF(func, sys_feature, "sys.feature")
#define SYS_FEATURE_INIT_PRI(func, priority) LAYER_INITCALL(func, sys_feature, "sys.feature", priority)
#define SYS_RUN(func) LAYER_INITCALL_DEF(func, run, "run")
#define SYS_RUN_PRI(func, priority) LAYER_INITCALL(func, run, "run", priority)
#define SYSEX_SERVICE_INIT(func) LAYER_INITCALL_DEF(func, app_service, "app.service")
#define SYSEX_SERVICE_INIT_PRI(func, priority) LAYER_INITCALL(func, app_service, "app.service", priority)
#define SYSEX_FEATURE_INIT(func) LAYER_INITCALL_DEF(func, app_feature, "app.feature")
#define SYSEX_FEATURE_INIT_PRI(func, priority) LAYER_INITCALL(func, app_feature, "app.feature", priority)
#define APP_SERVICE_INIT(func) LAYER_INITCALL_DEF(func, app_service, "app.service")
#define APP_SERVICE_INIT_PRI(func, priority) LAYER_INITCALL(func, app_service, "app.service", priority)
#define APP_FEATURE_INIT(func) LAYER_INITCALL_DEF(func, app_feature, "app.feature")
#define APP_FEATURE_INIT_PRI(func, priority) LAYER_INITCALL(func, app_feature, "app.feature", priority)

编写测试demo。

VOID TaskSampleEntry1(VOID) // 任务1的入口函数
{
    while(1) {
      LOS_TaskDelay(LOS_MS2Tick(2000));
      HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_2);
      HILOG_INFO(HILOG_MODULE_MAIN, "This is an electric light program.");
    //   PRINTK("This is an electric light program.\r\n");
    }
}

UINT32 TaskSample(VOID)
{
    UINT32 uwRet;
    UINT32 taskID1,taskID2;
    TSK_INIT_PARAM_S stTask1={0};
    stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry1;
    stTask1.uwStackSize  = 0X1000;
    stTask1.pcName       = "taskSampleEntry1";
    stTask1.usTaskPrio   = 6; //stTask1的任务优先级设定,不同于stTask2
    uwRet = LOS_TaskCreate(&taskID1, &stTask1);
    if(uwRet != LOS_OK)
    {
        PRINT_ERR("start_task init error.\r\n");
    }
    return LOS_OK;
}

SYS_RUN(TaskSample);

hb build之后,重新下载运行。电灯成功。说明SYS_RUN()运行有效。

bootstrap加入acts兼容性测试

device/board/fx/tunnel_box/liteos_m/boot/BUILD.gn

config("public") {
  include_dirs = [
    "include",
  ]

  ldflags = [
    "-Wl,-T" + rebase_path("STM32F407ZGTx_FLASH.ld"),
    "-Wl,-u_printf_float",
  ]

  if (build_xts) {
    lib_dirs = [ "$root_out_dir/libs" ]

    ldflags += [
      "-Wl,--whole-archive",
      "-lbootstrap",
      "-lbroadcast",
      "-lhctest",

      #公共基础库
    #   "-lmodule_ActsUtilsFileTest",
    #   "-lmodule_ActsKvStoreTest",

      #DFX
    #   "-lmodule_ActsDfxFuncTest",
    #   "-lmodule_ActsHieventLiteTest",

      #启动恢复
      "-lmodule_ActsBootstrapTest",  
      # "-lmodule_ActsParameterTest",

      #分布式任务调度
    #   "-lmodule_ActsSamgrTest",

      "-Wl,--no-whole-archive",
    ]
  }

  libs = [
    "c",
    "m",
    "nosys",
  ]
}

```hb build``之后,下载到板子中运行现实如下信息:

Run test suite 1 times
[TestStartBootstrapSamgr001:0]../../../test/xts/acts/startup_lite/bootstrap_hal/src/samgr_api_test.c:342:TestStartBootstrapSamgr001:PASS
g_coreInit0: 01: 0default: 03: 04: 05: 0../../../test/xts/acts/startup_lite/bootstrap_hal/src/samgr_api_test.c:353:TestStartBootstrapSamgr002:PASS
g_sysServiceInit0: 01: 0default: 03: 04: 05: 0../../../test/xts/acts/startup_lite/bootstrap_hal/src/samgr_api_test.c:365:TestStartBootstrapSamgr003:PASS
g_sysFeatureInit0: 01: 0default: 03: 04: 05: 0../../../test/xts/acts/startup_lite/bootstrap_hal/src/samgr_api_test.c:377:TestStartBootstrapSamgr004:PASS
g_sysExServiceInit0: 01: 0default: 03: 04: 05: 0g_appServiceInit0: 01: 0default: 03: 04: 05: 0../../../test/xts/acts/startup_lite/bootstrap_hal/src/samgr_api_test.c:389:TestStartBootstrapSamgr005:PASS
g_sysExFeatureInit0: 01: 0default: 03: 04: 05: 0g_appFeatureInit0: 01: 0default: 03: 04: 05: 0../../../test/xts/acts/startup_lite/bootstrap_hal/src/samgr_api_test.c:403:TestStartBootstrapSamgr006:PASS
g_sysRun0: 01: 0default: 03: 04: 05: 0../../../test/xts/acts/startup_lite/bootstrap_hal/src/samgr_api_test.c:417:TestStartBootstrapSamgr007:PASS
+-------------------------------------------+

-----------------------
7 Tests 0 Failures 0 Ignored 
OK
All the test suites finished!

bootstrap加入acts兼容性测试成功

补充非对齐访问的问题

根据STM32 Cortex®-M4 MCUs and MPUs programming manual - Programming manual的说法,cortex-m4支持非对齐访问。不对齐访问比对齐访问要慢,而且有些存储区域不支持非对齐访问。所以arm官方建议对齐访问。如下图所示:

address alignment.png

为了使用非对齐访问,需要将寄存器NVIC_CCR中的UNALIGN_TRP位清零。当UNALIGN_TRP=0时,非对齐访问就不会触发usage fault。
liteos_m中make menuconfig可以关闭对齐访问操作。如下图所示:


unalign.png

这样的话就可以在不改源码的情况下,解决对齐访问的问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容