pre_start属于加载函数,我们可以在loader/si/loader.c中找到它,我们还是把它复制到这里
 
void pre_start(void)
{
#ifdef debug
        loader();
#endif
        int_init();
 
        critical();
#ifndef debug
        loader();
#endif
    start_sys();        //开始启动系统
}
 
这里有个宏debug,debug已经在eclipse中定义具体是在工程properties > c/c++Build > Settings >preprocessor中,所以一开始就要调用loader(),loader与pre_loader()功能差不多,这里是把剩余的需要复制到ram里的代码段数据段复制到ram中。然后就是执行int_init()函数,这个函数是完成中断的初始化,我们一会在看。继续就是执行critical()钩子函数,就是在启动系统之前需要做的紧急任务在此完成。最后启动系统start_sys().
这里我们详细看一下int_init()这个函数:
关于中断djyos定义了两个结构:
1、中断线数据结构,每中断一个
//移植敏感
struct int_line
{
    u32 (*ISR)(ufast_t line);
    struct  event_ECB *sync_event;       //正在等待本中断发生的事件
    ucpu_t en_counter;          //禁止次数计数,等于0时表示允许中断
    ucpu_t int_type;            //1=实时中断,0=异步信号
    bool_t enable_nest;         //true=本中断响应期间允许嵌套,对硬件能力有依赖
                                //性,也与软件设置有关。例如cortex-m3版本,异步
                                //信号被设置为最低优先级,从而所有异步信号都不
                                //允许嵌套。
                                //特别注意,实时中断能够无条件嵌套异步信号。
                                //中断响应后,由中断引擎根据enable_nest的值使能
                                //或禁止中断来控制是否允许嵌套,如果在响应中断
                                //后,硬件没有立即禁止中断,将有一个小小的"窗口"
                                //,在该窗口内,是允许嵌套的。例如cm3的实时中断
 
    uint16_t my_evtt_id;
    u32  prio;                  //优先级,含义由使用者解析
};
 
2.中断总控数据结构.
struct int_master_ctrl
{
    //中断线属性位图,0=异步信号,1=实时中断,数组的位数刚好可以容纳中断数量,与
    //中断线数据结构的int_type成员含义相同。
    ucpu_t  property_bitmap[cn_int_bits_words];
    ucpu_t nest_asyn_signal;   //中断嵌套深度,主程序=0,第一次进入中断=1,依次递加
    ucpu_t nest_real;   //中断嵌套深度,主程序=0,第一次进入中断=1,依次递加
    //中断线使能位图,1=使能,0=禁止,反映相应的中断线的控制状态,
    //与总开关/异步信号开关的状态无关.
    ucpu_t  enable_bitmap[cn_int_bits_words];
//    bool_t  en_trunk;           //1=总中断使能,  0=总中断禁止
//    bool_t  en_asyn_signal;         //1=异步信号使能,0=异步信号禁止
    ucpu_t en_trunk_counter;   //全局中断禁止计数,=0表示允许全局中断
    ucpu_t en_asyn_signal_counter; //异步信号禁止计数,=0表示允许异步信号
};
 
熟悉了以上两个结构我们看一下中断初始化函数,过程已经详细注释,函数主要初始化了向量表,初始化了中断线数据结构,初始化中断总控数据结构
 
//----初始化中断---------------------------------------------------------------
//功能:初始化中断硬件,初始化中断线数据结构
//      2.异步信号保持禁止,它会在线程启动引擎中打开.
//      3.总中断允许,
//      用户初始化过程应该遵守如下规则:
//      1.系统开始时就已经禁止所有异步信号,用户初始化时无须担心异步信号发生.
//      2.初始化过程中如果需要操作总中断/实时中断/异步信号,应该成对使用.禁止使
//        异步信号实际处于允许状态(即异步和总中断开关同时允许).
//      3.可以操作中断线,比如连接、允许、禁止等,但应该成对使用.
//      4.建议使用save/restore函数对,不要使用enable/disable函数对.
//参数:无
//返回:无
//-----------------------------------------------------------------------------
void int_init(void)
{
    ufast_t ufl_line;
    int_cut_trunk();    //关总中断                                     
    int_echo_all_line();//此行动作for(ufl=0; ufl < cn_int_bits_words; ufl++)                                              //pg_int_reg->clrpend[ufl] = 0xffffffff;
                        //清除全部中断线的挂起
    pg_scb_reg->CCR |= 1<<bo_scb_ccr_usersetmpend;//USERSETMPEND  如果写成1,那么用户代码可
                                                 //以写软件触发中断寄存器以触发(挂起)一个主异
                                                 //常,该异常是和主堆栈指针相联系的。
    for(ufl_line=0;ufl_line <= cn_int_line_last;ufl_line++)
    {
        tg_int_lookup_table[ufl_line] = (ufast_t)cn_limit_ufast;
        u32g_vect_table[ufl_line] = (u32)__start_asyn_signal;  //全部初始化为异步信号 此数组为中断                    //向量表,预加载时已经加载到RAM,现在是将数组全部初始化为异步信号处理的入口地址
    }
    for(ufl_line=0;ufl_line < ufg_int_used_num;ufl_line++)
    {
        tg_int_lookup_table[tg_int_used[ufl_line]] = ufl_line;
        tg_int_table[ufl_line].en_counter = 1;                   //禁止中断,计数为1
        tg_int_table[ufl_line].int_type = cn_asyn_signal;        //设为异步信号
                                                                 //所有中断函数指针指向空函数
        tg_int_table[ufl_line].ISR = (u32 (*)(ufast_t))NULL_func;
        tg_int_table[ufl_line].sync_event = NULL;                //同步事件空
        tg_int_table[ufl_line].my_evtt_id = cn_invalid_evtt_id;  //不弹出事件
        pg_int_reg->pri[ufl_line] = 0xff;                        //异步信号优先级最低
    }
    for(ufl_line=0; ufl_line < cn_int_bits_words; ufl_line++)
    {
        pg_int_reg->clrena[ufl_line]=0xffffffff;     //全部禁止
        pg_int_reg->clrpend[ufl_line]=0xffffffff;    //全部清除挂起状态
        //属性位图清零,全部置为异步信号方式
        tg_int_global.property_bitmap[ufl_line] = 0;
        //中断使能位图清0,全部处于禁止状态
        tg_int_global.enable_bitmap[ufl_line] = 0;
    }
    tg_int_global.nest_asyn_signal =0;
    tg_int_global.nest_real=0;
 
//    tg_int_global.en_asyn_signal = false;
    tg_int_global.en_asyn_signal_counter = 1;   //异步信号计数
    int_cut_asyn_signal();
//    tg_int_global.en_trunk = true;
    tg_int_global.en_trunk_counter = 0;       //总中断计数
    int_contact_trunk();                    //接通总中断开关
    cm3_cpsie_f();                           //接通所有异常开关
}
 
 
这里介绍一个eclipse的快捷键,Ctrl+h  可以调出查询对话框,可以在工作区查找字符串 函数等,很方便.
中断初始化已经完成,接下来就是开始启动系统了,下一篇我们再看.有些底层函数我们可能到系统启动完成都没有涉及到,是因为必须有中断或者调用才会涉及到,以后的时间我们看一下,现在主要是看一下系统是怎样启动的。