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

📄 djyos.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
        y_error_login(enum_knl_no_free_etcb,"没有空闲事件控制块");
        int_restore_asyn_signal();
        return cn_invalid_evtt_id;
    }else if(evtt_name != NULL) //新类型有名字,需检查有没有重名
    {
        for(i=0; i<cn_evtts_limit; i++)
        {
		    if(strcmp(tg_evtt_table[i].evtt_name,evtt_name) == 0)
			{
                y_error_login(enum_knl_evtt_homonymy,"事件类型重名");
                int_restore_asyn_signal();
                return cn_invalid_evtt_id;
			}
        }
        if(rtstrlen(evtt_name,31) != cn_limit_uint32)
            strcpy(tg_evtt_table[evtt_id].evtt_name,evtt_name);
        else
        {
            memcpy(tg_evtt_table[evtt_id].evtt_name,evtt_name,31);
            tg_evtt_table[evtt_id].evtt_name[31] = '\0';
        }
    }
    tg_evtt_table[evtt_id].property = (struct evtt_property){0,0,1,0};
    tg_evtt_table[evtt_id].property.mark = mark;
    tg_evtt_table[evtt_id].property.overlay = overlay;
    tg_evtt_table[evtt_id].my_free_vm = NULL;
    tg_evtt_table[evtt_id].default_prio = default_prio;
    tg_evtt_table[evtt_id].pop_sum = 0;
    tg_evtt_table[evtt_id].done_sum = 0;
    tg_evtt_table[evtt_id].repeats = 0;
    tg_evtt_table[evtt_id].vpus_limit = vpus_limit;
    tg_evtt_table[evtt_id].thread_routine = thread_routine;
    tg_evtt_table[evtt_id].stack_size = stack_size;
    tg_evtt_table[evtt_id].mark_unclear = NULL;
    tg_evtt_table[evtt_id].done_sync = NULL;
    tg_evtt_table[evtt_id].pop_sync = NULL;
    if((cn_run_mode!=cn_mode_mp)||(default_prio<0x80))
    {//运行模式为si或dlsp,或该事件类型拥有紧急优先级,需预先创建一个线程虚拟机
        tg_evtt_table[evtt_id].my_free_vm =
                                __create_thread(&tg_evtt_table[evtt_id]);
        if(tg_evtt_table[evtt_id].my_free_vm == NULL)
        {//内存不足,不能创建虚拟机
            y_error_login(enum_mem_tried,"创建虚拟机时内存不足");
            return cn_invalid_evtt_id;
        }else
            tg_evtt_table[evtt_id].vpus = 1;
    }else
        tg_evtt_table[evtt_id].vpus = 0;
    int_restore_asyn_signal();
    return evtt_id;
}

//----取事件类型id-------------------------------------------------------------
//功能:根据事件类型的名字,返回该事件类型的id号,不查找没名字的事件类型。
//参数:evtt_name,事件类型名
//返回:事件类型id号,如果没有找到则返回cn_invalid_id。
//备注:只能找到有名字的事件类型,没名字的事件类型又叫隐身事件类型。
//----------------------------------------------------------------------------
uint16_t y_get_evtt_id(char *evtt_name)
{
    uint16_t loop;
    if(evtt_name == NULL)
        return cn_invalid_evtt_id;
    for(loop = 0; loop < cn_evtts_limit; loop++)
    {
        if(strcmp(tg_evtt_table[loop].evtt_name,evtt_name) ==0)
            return loop;
    }
    return cn_invalid_evtt_id;
}

//----删除事件类型-------------------------------------------------------------
//功能: 删除一个事件类型,如果队列中还有该类型事件(in_use == 1),只标记该类型为被
//      删除,真正的删除工作是在 done函数里完成的.如果队列中已经没有该类型事件了,
//      将会执行真正的删除操作.无论哪种情况,系统均会拒绝弹出该类型的新事件.
//参数: evtt_id,待删除的事件类型号
//返回: true = 成功,包括成功标记;false = 失败
//-----------------------------------------------------------------------------
bool_t y_evtt_unregist(uint16_t evtt_id)
{
    struct thread_vm *next_vm,*temp;
    struct event_type *evtt;
    bool_t result = true;
    if(evtt_id >= cn_evtts_limit)
        return false;
    evtt = &tg_evtt_table[evtt_id];
    if((evtt->property.in_use)||(evtt->done_sync != NULL)
                              || (evtt->pop_sync != NULL))
    {
        //事件类型正在使用或完成同步和弹出同步队列非空,不允许删除
        result = false;
    }else
    {
        next_vm = evtt->my_free_vm;
        //回收事件类型控制块,只需把registered属性清零。
        evtt->property.registered = 0;
        evtt->evtt_name[0] = '\0';  //清空事件类型名
        while(next_vm != NULL)        //释放该事件类型拥有的空闲虚拟机
        {
            temp = next_vm;
            next_vm = next_vm->next;
            m_free((void *)temp);
        }
    }
    return result;
}

//----建立事件链表-------------------------------------------------------------
//功能:1.根据系统设定初始化操作系统虚拟机和事件表指针
//      2.把 cn_events_limit 个事件控制块结构连接成一个空闲队列,队列的结构参见
//        文档,由指针pg_free_event索引,
//参数:无
//返回:无
//-----------------------------------------------------------------------------
void __y_init_sys(void)
{
    uint16_t i;
    struct thread_vm *vm;
    pg_event_delay=NULL;    //延时事件链表空

    //把事件类型表全部置为没有注册,0为系统服务类型
    for(i=1; i<cn_evtts_limit; i++)
    {
        tg_evtt_table[i].property.registered = 0;
    }
    for(i = 1; i < cn_events_limit; i++)    //i=0为系统服务事件
    {
        if(i==(cn_events_limit-1))
            tg_event_table[i].next = NULL;
        else
            tg_event_table[i].next = &tg_event_table[i+1];
        //向前指针指向pg_event_free的地址,说明这事个空闲事件块.
        //没有别的含义,只是找一个唯一且不变的数值,全局变量地址在整个运行期
        //是不会变化的.
        tg_event_table[i].previous = (struct  event_script*)&pg_event_free;
        tg_event_table[i].event_id = i;    //本id号在程序运行期维持不变
    }
    pg_event_free = &tg_event_table[1];

    tg_evtt_table[0].property = (struct evtt_property){1,0,1,1};
    tg_evtt_table[0].my_free_vm = NULL;
    tg_evtt_table[0].evtt_name[0] = '\0';
    tg_evtt_table[0].default_prio = cn_prio_sys_service;
    tg_evtt_table[0].pop_sum = 0;
    tg_evtt_table[0].done_sum = 0;
    tg_evtt_table[0].repeats = 1;
    tg_evtt_table[0].vpus_limit =1;
    tg_evtt_table[0].vpus = 1;
    tg_evtt_table[0].thread_routine = __os_service;
    tg_evtt_table[0].stack_size = 1024;
    tg_evtt_table[0].mark_unclear = tg_event_table;
    tg_evtt_table[0].done_sync = NULL;
    tg_evtt_table[0].pop_sync = NULL;

    vm = __create_thread(&tg_evtt_table[0]);
    if(vm == NULL)      //内存不足,不能创建常驻虚拟机
    {
        y_error_login(enum_mem_tried,"创建虚拟机时内存不足");
        tg_evtt_table[0].vpus = 0;
        return ;
    }
    //以下模拟popup函数,弹出系统服务事件.当事件队列为空时,调用popup的结果
    //是不可预知的.由于系统运行时,系统服务事件总在队列中,所以事件队列是不会空
    //的,这里模拟popup事件,而不是直接调用,可以使popup函数中省掉一个判断队列是否
    //空的操作.
    tg_event_table[0] = (struct event_script){
                        tg_event_table,tg_event_table,  //next,previous
                        tg_event_table,tg_event_table,//multi_next,multi_previous
                        vm,                         //vm
                        NULL,                       //sync
                        NULL,                       //sync_head
                        0,                          //start_time
                        0,                          //consumed_time
                        0,                          //delay_start
                        0,                          //delay_end
                        enum_knl_no_error,            //error_no
                        0,0,                        //parameter0,parameter1
                        0,                          //wait_mem_size
                        {0},                          //last_status
                        {0},                          //event_status
                        cn_prio_sys_service,        //prio
                        0,                          //evtt_id
                        0,                          //sync_counter
                        0,                          //event_id
                        1,                          //repeats
                        NULL,0                   //held_device,local_memory
                        };
    tg_event_table[0].event_status.bit.event_ready = 1;
    pg_event_ready = tg_event_table;
    pg_event_running = pg_event_ready;
}

//--------检查是否允许调度------------------------------------------------------
//功能: 检查是否允许调度,允许异步信号且运行在线程态时,允许调度
//参数: 无
//返回: 允许调度返回true,否则返回false
//-----------------------------------------------------------------------------
bool_t y_query_sch(void)
{
    return ((tg_int_global.en_asyn_signal)
                && (tg_int_global.nest_asyn_signal == 0)
                && (tg_int_global.en_trunk));
}

//----把事件插入就绪队列中----------------------------------------------------
//功能:把事件插入到就绪队列中合适的位置,该事件原来不在就绪队列中.
//参数:event_ready,待插入的事件,该事件原来不在就绪队列中
//返回:无
//------------------------------------------------------------------------------
void __y_event_ready(struct  event_script *event_ready)
{
    struct  event_script *event;
    int_save_asyn_signal();
    event_ready->event_status.bit.event_ready = 1;
    event = pg_event_ready;
    do
    { //找到一个优先级低于新事件的事件.由于系统服务事件总是ready,因此总是能找到.
        if(event->prio <= event_ready->prio)
            event = event->next;
        else
            break;
    }while(event != pg_event_ready);
    event_ready->next = event;
    event_ready->previous = event->previous;
    event->previous->next = event_ready;
    event->previous = event_ready;

    //新插入的事件在同优先级的最后,故这样能够判断新事件是否该优先级的唯一事件。
    //若是该优先级的唯一事件,也即是该优先级首事件,则需要将其插入首事件链表
    if(event_ready->prio != event_ready->previous->prio)
    {
        event = event_ready->next;
        event->multi_previous->multi_next = event_ready;
        event_ready->multi_previous = event->multi_previous;
        event->multi_previous = event_ready;
        event_ready->multi_next = event;
    }else       //不是该优先级的首事件
    {
        event_ready->multi_next = NULL;
        event_ready->multi_previous = NULL;
    }
    if(event_ready->prio < pg_event_ready->prio)
        pg_event_ready = event_ready;
    int_restore_asyn_signal();
}

//----退出闹钟同步队列---------------------------------------------------------
//功能: 把一个事件从闹钟同步队列中取出,不管闹铃时间是否已经到达.用在带超时的同步
//      功能中,当同步条件先于超时时限到达时,从闹钟同步队列取出事件。
//参数: delay_event,待处理的事件.
//返回: 无
//备注: 1.本函数不开放给用户,仅仅是操作系统内部使用.操作系统不给用户提供提前
//      退出延时的功能,这样可以防止事件间互相干涉
//      2.本函数应该在关闭调度条件下调用,调用者保证,函数内部不检查中断状态.
//      3.本函数只把事件从闹钟同步链表中取出,并不放到就绪队列中。
//-----------------------------------------------------------------------------
void __y_resume_delay(struct  event_script *delay_event)
{
    if(pg_event_delay->next == pg_event_delay)  //队列中只有一个事件
        pg_event_delay = NULL;
    else
    {
        if(delay_event == pg_event_delay)
            pg_event_delay = pg_event_delay->previous;
        delay_event->next->previous = delay_event->previous;
        delay_event->previous->next = delay_event->next;
    }
    delay_event->next = NULL;
    delay_event->previous = NULL;
    delay_event->delay_end = y_get_time();
}

//----加入延时队列------------------------------------------------------------
//功能:由正在执行的事件调用,直接把自己加入延时队列,不引起调度也不操作ready
//      队列,一般由同步函数调用,在timeout!=0时把事件加入闹钟同步队列实现
//      timeout功能,是特定条件下对y_timer_sync函数的简化。
//参数:u32l_mS,延迟时间,单位是毫秒,将被向上调整为cn_tick_ms的整数倍
//返回:无
//备注:1、操作系统内部使用的函数,且需在关闭中断(禁止调度)的条件下使用。
//      2、调用本函数是running事件已经从就绪表中取出,本函数不改变就绪表。

⌨️ 快捷键说明

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