2021 乐鑫笔试题目

乐鑫笔试题目之软件定时器实现

2021年秋招乐鑫面试题目:用硬件定时器实现多个软件timer

1、题目介绍

1.1、已知硬件定时器API

1、u32 get_now();获取系统当前时间,可以理解为硬件tick。(已经实现好,可以直接调用)
2、void set_timer_start(u32 expire_time); 开启硬件定时器,一段时间之后到达expire_time时调用硬件timer函数。(已经实现好,可以直接调用)
3、void timer_fired();硬件中断服务函数

1.2、软件API

1、void timer_start(struct soft_timer T); 用户传入结构T,可以供多个用户调用,结构体T 需要实现。

1.3、求实现:

1、结构体T的定义;
2、timer_start() 的实现;
3、timer_fired() 的实现;

总的下来意思就是使用一个硬件timer实现多个软件timer,如果每个任务都使用硬件timer,那么只有一个硬件timer,根本没法支持多个一起使用,后面的硬件timer调用可能导致前面的timer调用失效

所以就是用数据结构来管理硬件timer,实现多个软件timer 共用一个硬件timer。

2、代码实现

2.1、软件timer数据结构定义如下
  • interval:定时间隔,一般定时器需要该参数指明定时间隔
  • expire_time:截止时间,getnow + interval 来填充,方便调用 set_timer_start 函数,
  • soft_timer_callbackargs:回调函数以及参数,
  • is_repeat:是否是重复的timer函数
  • next:指明下一个执行的timer函数,管理使用timer的函数。

当然如果硬件timer API的实现是如下:
void set_timer_start(u32 interval),也可以实现,看下面介绍

typedef (*soft_timer_callback)(void*);
struct soft_timer 
{
    u32 interval;
    u32 expire_time;
    soft_timer_callback  callback;
    void *args;
    bool_t is_repeat;
    struct soft_timer* next;
};
2.1、硬件timer中断函数实现

主要是调用用户的回调函数,以及启动下一个定时任务函数

void timer_fired()
{
    struct soft_timer* temp_timer = soft_timer_ready_list;
    soft_timer_ready_list = soft_timer_ready_list->next;

    (*temp_timer->callback)(temp_timer->args); //call the min interval user callback func
    
    if(temp_timer->is_repeat) // add the ready list 
    {
        temp_timer->expire_time = get_now() + temp_timer->interval;
        timer_add_ready_list(temp_timer);
    }
    if(soft_timer_ready_list->next) 
    {
        set_timer_start(soft_timer_ready_list->expire_time - get_now()); // start the next user timer 
    }
}

当然笔者是在中断中调用用户函数,如果时间执行时间较长可能影响其他任务或者中断,优化之后,可以在主函数中去执行,中断里面只是做标志位检查,然后主函数判断标志位,并去执行。


bool_t interrupt_flag = false;
void timer_fired()
{
	interrupt_flag = true;
}

void soft_timer_excution_func()
{
	if(true == interrupt_flag )
	{
		interrupt_flag = false;
		struct soft_timer* temp_timer = soft_timer_ready_list;
	    soft_timer_ready_list = soft_timer_ready_list->next;
	
	    (*temp_timer->callback)(temp_timer->args); //call the min interval user callback func
	    
	    if(temp_timer->is_repeat) // add the ready list 
	    {
	        temp_timer->expire_time = get_now() + temp_timer->interval;
	        timer_add_ready_list(temp_timer);
	    }
	    if(soft_timer_ready_list->next) 
	    {
	        set_timer_start(soft_timer_ready_list->expire_time - get_now()); // start the next user timer 
	    }
	}
}
int main()
{
	....
	while(1)
	{
		....
		soft_timer_excution_func();
		....
	}
}

仔细在思考一下上面的代码,假如两个timer同时到达,会发生什么情况,我们只处理了第一个timer,调用了callback,

然后start 第二个 函数,其实第二个timer的截止时间已经到了,那么可能立即又中断,也可能出现异常,取决于硬件timer的健壮性,因为设置的时间为0,timer间隔的时间。

所以需要增加一个循环来判断一下,来对上面代码进行优化一下。

void soft_timer_excution_func()
{
	if(true == interrupt_flag )
	{
		interrupt_flag = false;

        while((soft_timer_ready_list != NULL) && (soft_timer_ready_list->expire_time <= get_now()))  //loop check timer interval is ok
        {
            struct soft_timer* temp_timer = soft_timer_ready_list;
            soft_timer_ready_list = soft_timer_ready_list->next;
        
            (*temp_timer->callback)(temp_timer->args); //call the min interval user callback func
            
            if(temp_timer->is_repeat) // add the ready list 
            {
                temp_timer->expire_time = get_now() + temp_timer->interval;
                timer_add_ready_list(temp_timer);
            }
        }

        if(soft_timer_ready_list)  //start the first timer func
        {
            set_timer_start(soft_timer_ready_list->expire_time - get_now()); // start the next user timer 
        }

	}
}

当然中断函数也可以进行优化,但是就不太合适,因为中断函数里面不太适合放较多的函数,尤其是while循环这种。

2.2、就绪软件timer 链表插入

链表有序插入用户的软件timer节点,管理用户软件timer的执行。
需要注意:

  • 当用户传的节点为空时,以及有序链表头节点为空时
  • 插入到第一个节点时,即当前的任务间隔最小
  • 插入到中间时,需要记录上一个节点,然后完成节点之间的连接
  • 插入到末尾时,next = null
struct soft_timer* soft_timer_ready_list;
void timer_add_ready_list(struct soft_timer* T)
{
    struct soft_timer*  ready_list_temp = soft_timer_ready_list;
    if((NULL == T))  // user node is null 
    {
    	/* nothing process */
    }
    else if(NULL == ready_list_temp) //read list is null or header node is null 
    {
        ready_list_temp = T;
        ready_list_temp->next = LS_NULL;
    }
    else if(T->expire_time <= ready_list_temp->expire_time) // first node 
    {
        T->next = ready_list_temp;
        ready_list_temp = T;
    }
    else
    {
        struct soft_timer*  last_timer_node = ready_list_temp;
        while((NULL != ready_list_temp) && (ready_list_temp->expire_time < T->expire_time))
        {
            last_timer_node = ready_list_temp;
            ready_list_temp = ready_list_temp->next;
        }
        if(NULL == ready_list_temp) // the last node 
        {
            last_timer_node->next = T;
            T->next = LS_NULL;
        }
        else // the middle node
        {
            last_timer_node->next = T;
            T->next = ready_list_temp;
        }
    }
}
2.3、timer 启动函数

timer start 函数,就是负责传入用户的软件timer函数信息,然后开始执行时间间隔最小的定时。

void timer_start(struct soft_timer T)
{
    timer_add_ready_list(&T);
    if(NULL != soft_timer_ready_list)
    {
        set_timer_start(soft_timer_ready_list->expire_time);
    }
}

当然如果硬件timer set_timer_start(int interval),那么此时的函数就应该如下这样写:

void timer_start(struct soft_timer T)
{
    timer_add_ready_list(&T);
    if(NULL != soft_timer_ready_list)
    {
        set_timer_start(soft_timer_ready_list->expire_time - get_now());
    }
}

上面的中断函数timer_fired() 里面的调用,同样也是需要减去 get_now()。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
科技是一家专注于物联网芯片和解决方案的公司,它在C语言方面开展了一场笔试。C语言是一种广泛使用的、通用的高级编程语言,它为开发者提供了底层控制硬件的能力。 在科技的C语言笔试中,可能会包含以下内容:基本语法、数据类型、运算符、控制结构、函数、数组、指针、结构体等。基本语法是最基础的部分,包括如何定义变量、如何使用注释、如何编写函数等。数据类型是C语言中的基本类型,包括整型、浮点型、字符型等,掌握不同数据类型的使用规则至关重要。运算符包括赋值运算符、算术运算符、关系运算符等,它们用于对数据进行操作和比较。控制结构包括条件语句(如if语句)和循环语句(如for循环),它们可以根据条件控制程序的执行流程。函数是C语言中的一个重要概念,它用于封装独立的功能模块,提高代码的可读性和重用性。数组是一组具有相同数据类型的元素的集合,指针则提供了直接访问内存地址的能力,结构体则用于组合多个不同类型的数据。 通过科技的C语言笔试,考察者将能够了解到考生对C语言的掌握程度和编程能力。C语言是一门重要的编程语言,在物联网行业尤为重要,因此掌握C语言的基本知识和技能对于科技的求职者来说是非常有帮助的。希望通过这场笔试,考生们能够展示出自己的才华和能力,为进一步的面试和招聘机会铺平道路。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张一西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值