⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 djyos.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        pg_event_running->event_status.bit.evtt_done_sync = 0;
        int_restore_asyn_signal();
        return cn_sync_timeout;
    }else
    {
        int_restore_asyn_signal();
        return cn_sync_success;
    }
}
//----事件类型弹出同步---------------------------------------------------------
//功能: 把正在运行的事件加入到指定事件类型的弹出同步队列中去,然后重新调度。弹出
//      同步是指以该事件类型的事件弹出若干次为同步条件。
//参数: evtt_id,目标事件类型号
//      pop_times,弹出次数,不能是0.
//      timeout,超时设置,单位是毫秒,cn_timeout_forever=无限等待,0则立即按
//      超时返回。非0值将被向上调整为cn_tick_ms的整数倍
//返回: cn_sync_success=同步条件成立返回,
//      cn_sync_timeout=超时返回,
//      cn_sync_error=出错,
//      本函数必须联系共享文档的相关章节才容易读懂,注释难于解释那么清楚的。
//----------------------------------------------------------------------------
uint32_t y_evtt_pop_sync(uint16_t evtt_id,uint16_t pop_times,uint32_t timeout)
{
    struct  event_type *evtt;
    struct event_script *pl_ecb;
    evtt = &tg_evtt_table[evtt_id];
    //不能在禁止调度的情况下执行同步操作,弹出次数不能设为0
    if((y_query_sch() == false) || (pop_times == 0))
        return cn_sync_error;
    if(timeout == 0)
        return cn_sync_timeout;
    int_save_asyn_signal();
    if(evtt->property.registered == false)
    {//该事件类型是无效事件类型
        int_restore_asyn_signal();
        return cn_sync_error;
    }
    __y_cut_ready_event(pg_event_running);
    pg_event_running->next = NULL;
    pg_event_running->previous = NULL;
    pg_event_running->sync_counter = pop_times;

    //以下把pg_event_running加入到目标事件的同步队列中
    pg_event_running->sync_head = &evtt->pop_sync;
    if(evtt->pop_sync != NULL)
    {//被同步事件的同步队列不是空的
        pl_ecb = evtt->pop_sync;
        do
        {//本循环找到第一个剩余弹出次数不小于新事件的事件.
            if(pl_ecb->sync_counter < pop_times)
                pl_ecb = pl_ecb->multi_next;
            else
                break;
        }while(pl_ecb != evtt->pop_sync);
        //下面把新事件(pg_event_running)插入到队列中
        pg_event_running->multi_next = pl_ecb;
        pg_event_running->multi_previous = pl_ecb->multi_previous;
        pl_ecb->multi_previous->multi_next = pg_event_running;
        pl_ecb->multi_previous = pg_event_running;
        if(evtt->pop_sync->sync_counter > pop_times)
            evtt->pop_sync = pg_event_running;
    }else
    {//被同步事件的同步队列是空的
        evtt->pop_sync = pg_event_running;
        pg_event_running->multi_next = pg_event_running;
        pg_event_running->multi_previous = pg_event_running;
    }

    pg_event_running->last_status.all = pg_event_running->event_status.all;
    pg_event_running->event_status.bit.evtt_pop_sync = 1;
    if(timeout != cn_timeout_forever)
    {
        pg_event_running->event_status.bit.wait_overtime = 1;
        __y_addto_delay((timeout + cn_tick_ms -1)/cn_tick_ms);
    }
    int_restore_asyn_signal();  //恢复中断会引发重新调度

    int_save_asyn_signal();
    //检查从哪里返回,是超时还是同步事件完成。
    if(pg_event_running->event_status.bit.evtt_pop_sync)
    {//说明同步条件未到,从超时返回,应从目标事件的同步队列中取出事件。
     //此时,同步条件肯定还没有达成。
        pg_event_running->event_status.bit.evtt_pop_sync = 0;
        int_restore_asyn_signal();
        return cn_sync_timeout;
    }else
    {
        int_restore_asyn_signal();
        return cn_sync_success;
    }
}
//----报告事件------------------------------------------------------------------
//功能:向操作系统报告发生事件,操作系统接报后,将分配或建立合适的线程处理事件.
//参数:event_type,发生的事件类型
//      parameter0,parameter1,事件参数
//      prio,事件优先级,0表示使用默认值(存在事件类型表pg_event_type_table中)
//返回:若不能获取事件控制块,返回-1,否则返回事件id。
//注: 不会因不能获得事件控制块而阻塞。
//------------------------------------------------------------------------------
uint16_t y_event_pop(   uint16_t evtt_id,
                        uint32_t parameter0,
                        uint32_t parameter1,
                        ufast_t prio)
{
    struct  event_script *pl_ecb;
    struct  event_type *pl_evtt;
    uint16_t result;
    ufast_t my_prio;
    if(evtt_id >= cn_evtts_limit)
        return cn_invalid_event_id;
    pl_evtt =&tg_evtt_table[evtt_id];
    if((pl_evtt->property.registered == 0)      //类型未登记
        || (prio >= cn_prio_sys_service))       //不能pop休眠事件
    {
        y_error_login(enum_knl_etcb_error,NULL);
        return cn_invalid_event_id;
    }

    int_save_asyn_signal(); //关异步信号(关调度)
    pl_evtt->pop_sum++;
    //下面处理弹出同步队列,必须联系共享文档的相关章节才容易读懂,注释难于解释
    //那么清楚的。
    while(pl_evtt->pop_sync != NULL)
    {
        pl_ecb = pl_evtt->pop_sync;
        if(pl_ecb->sync_counter == 1)
        {
            pl_ecb->last_status.all = pl_ecb->event_status.all;
            pl_ecb->event_status.bit.evtt_pop_sync = 0;
            if(pl_ecb->event_status.bit.wait_overtime)  //指定的超时未到
            {
                __y_resume_delay(pl_ecb);       //从闹钟队列中移除事件
                pl_ecb->event_status.bit.wait_overtime = 0;
            }
            if(pl_ecb->multi_next == pl_ecb->multi_previous)
            {//是最后一个事件
                pl_evtt->pop_sync = NULL;
            }else
            {
                pl_evtt->pop_sync = pl_ecb->multi_next;
                pl_ecb->multi_next->multi_previous = pl_ecb->multi_next;
                pl_ecb->multi_previous->multi_next = pl_ecb->multi_previous;
            }
            __y_event_ready(pl_ecb);
        }else
        {
            pl_ecb->sync_counter--;
        }
    }

//mark型事件需要正在执行的done才能执行新事件。
//mark型事件在队列中可能的组合为:
//  已clear                  repeats       处理方式
//       未clear  mark_unclear      in_use
//1  有     无         NULL   ==0     1    新事件由mark_unclear指针指向
//2  有     有        !NULL   !=0     1    repeats++,考虑参数替换
//3  无     有        !NULL   !=0     1    repeats++,考虑参数替换
//4  无     无         NULL   ==0     0    新事件加入就绪队列
    if(pl_evtt->mark_unclear != NULL)
    {// mark型事件的第2和第3种情况
        pl_ecb = pl_evtt->mark_unclear;         //取事件控制块
        if(pl_evtt->property.overlay == 1)  //参数替换型,替换参数
        {
            pl_ecb->parameter0 = parameter0;
            pl_ecb->parameter1 = parameter1;
        }
        if(pl_evtt->repeats != cn_limit_uint16)
            pl_evtt->repeats++;         //事件发生次数增量
        result = pl_ecb->event_id;
        goto end_pop;                                       //注意 goto
    }

    if(prio != 0)
        my_prio = prio; //设置事件优先级,
    else
        my_prio = pl_evtt->default_prio;       //从事件类型中继承优先级

    //以下处理非mark型事件或者mark型事件的第1、4种情况
    if(pg_event_free==NULL)     //没有空闲的事件控制块
    {
        y_error_login(enum_knl_no_free_ecb,NULL);
        result = cn_invalid_event_id;
    }else if((pl_evtt->property.mark == false)
                    && (pl_evtt->repeats >= pl_evtt->vpus_limit))
    {
        y_error_login(enum_knl_vpu_over,NULL);
        result = cn_invalid_event_id;
    }else                       //有空闲事件控制块
    {

        pl_ecb = pg_event_free;         //从空闲链表中提取一个事件控制块
        pg_event_free=pg_event_free->next;  //空闲事件控制块数量减1
        if(pl_evtt->repeats != cn_limit_uint16)
            pl_evtt->repeats++;         //repeats增量
        //设置新事件的参数
        pl_ecb->next = NULL;
        pl_ecb->previous = NULL;
        pl_ecb->multi_next = NULL;
        pl_ecb->multi_previous = NULL;
        pl_ecb->vm = NULL;
        pl_ecb->sync = NULL;
        pl_ecb->sync_head = NULL;
        pl_ecb->start_time=y_get_time();   //事件发生时间
        pl_ecb->consumed_time = 0;
        pl_ecb->delay_start = 0;
        pl_ecb->delay_end = 0;
        pl_ecb->error_no = 0;
        pl_ecb->parameter0=parameter0;          //设置事件参数
        pl_ecb->parameter1=parameter1;          //设置事件参数
        pl_ecb->wait_mem_size = 0;
        pl_ecb->last_status.all = 0;
        pl_ecb->event_status.all = 0;
        pl_ecb->prio = my_prio;
        pl_ecb->evtt_id=evtt_id;          //设置事件类型
        pl_ecb->repeats = 0;
        pl_ecb->held_device = NULL;
        pl_ecb->local_memory = 0;
        if(pl_evtt->property.mark == true)    //这是mark型事件
        {
            pl_evtt->mark_unclear = pl_ecb;
            if(pl_evtt->property.in_use == 1)   //第1种情况
            {
            }else                               //第4种情况
            {
                __y_event_ready(pl_ecb);
            }
        }else                                   //非mark型事件
            __y_event_ready(pl_ecb);
        pl_evtt->property.in_use = 1;
        result = pl_ecb->event_id;
    }


end_pop:
    int_restore_asyn_signal();  //恢复中断状态
    return result;
}

//----初始化tick---------------------------------------------------------------
//功能: 初始化定时器,并连接tick中断函数,启动定时器.
//参数: 无
//返回: 无
//备注: 本函数是移植关键函数.
//-----------------------------------------------------------------------------
void __y_init_tick(void)
{
    //连接timer5作为tick中断
    int_isr_connect(cn_irq_line_timer5,__y_isr_tick);
    int_setto_asyn_signal(cn_irq_line_timer5);          //tick中断被设为异步信号
    //以下设置定时器参数,需与port_config.h中cn_tick_ms、cn_tick_hz和
    //cn_fine_us、cn_fine_hz的定义一致
    timer_set_clk_source(5,0);          //主频的1/2分频
    timer_set_precale(2,7);            //预分频数:32分频
    //以上把定时器输入时钟的频率设为1M,与常数cn_fine_hz对应
    timer_set_counter(5,(uint16_t)(cn_tick_ms*cn_timer_clk/16000));
    timer_set_type(5,1);                //设置tick定时器连续工作
    timer_reload(5);                    //重载定时值
    timer_start(5);                     //启动定时器
    int_restore_line(cn_irq_line_timer5);//启动tick中断
}
//----启动操作系统--------------------------------------------------------------
//功能: 初始化时钟嘀嗒,复位异步信号使能状态,选出最高优先级事件,调用
//      __asm_turnto_context把上下文切换到这个事件
//参数: 无
//返回: 无
//_____________________________________________________________________________
void __y_start_os(void)
{
    __y_init_tick();
    //本句为容错性质,以防用户模块初始化过程中没有成对调用异步信号使能与禁止函数
    __int_reset_asyn_signal();
    __y_select_event_to_run();
    pg_event_running = pg_event_ready;
    __asm_turnto_context(pg_event_running->vm);
}

//----完成事件------------------------------------------------------------------
//功能:向操作系统报告事件已经完成,操作系统接到报告后,完成清理工作.
//      1.如果事件同步队列非空,把同步事件放到ready表。
//      2.如果持有设

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -