【问题标题】:Setting up a timer with Microblaze?用 Microblaze 设置计时器?
【发布时间】:2017-02-17 16:17:45
【问题描述】:

使用 Microblaze 创建计时器的最佳方法是什么,它可以让我在更传统的脚本中让它更类似于 delay_ms()sleep() 之类的功能?

很容易,我可以像这样创建一个愚蠢的函数:

void delay_ms(int i) {
    //mind that I am doing this on the top of my head
    for(delays=0; delay<(i*((1/frequency of the device)/2)); delays++) {
    }
}

...但这只会让处理器在它完成之前什么都不处理,而实际上我需要它具有允许我在某个时间段内停止一个进程而另一个进程继续工作的功能。

这样的事情是可能的,毫无疑问,但是解决这个问题的最简单的方法是什么?

(我使用的是 Spartan-3A,但我相信该解决方案也适用于不同的套件和 FPGA。)

【问题讨论】:

  • 您可以通过中断或信号来实现...但这取决于您如何对处理器进行编程。您使用任何操作系统吗?
  • 完全没有。我正在尝试尽可能轻松地做所有事情。
  • 你是如何运行多个进程的呢?
  • 我正在尝试使用已配置的硬件 xps 计时器。

标签: c timer fpga xilinx microblaze


【解决方案1】:

TL;DR

使用微型操作系统,例如FreeRTOS

错误答案

好吧,如果你没有操作系统,没有任务交换但有一个外部计时器,你可以 使用以下方法:

为您的硬件计时器启用中断,并管理由该中断驱动的计数器:

你应该有类似的东西

/**timer.c**/

/* The internal counters
 * each task have its counter
 */
static int s_timers[NUMBER_OF_TASKS] = {0,0};

/* on each time tick, decrease timers */
void timer_interrupt()
{
    int i;
    for (i = 0; i < NUMBER_OF_TASKS; ++i)
    {
        if (s_timer[i] > 0)
        {
            s_timer[i]--;
        }
    }
}

/* set wait counter:
 * each task says how tick it want to wait
 */
void timer_set_wait(int task_num, int tick_to_wait)
{
    s_timer[task_num] = tick_to_wait;
}

/**
 * each task can ask if its time went out
 */
int timer_timeout(int task_num)
{
    return (0 == s_timer[task_num]);
}

一旦你有了类似计时器的东西(上面的代码很容易完善), 规划你的任务:

/**task-1.c**/

/*TASK ID must be valid and unique in s_timer */
#define TASK_1_ID 0

void task_1()
{
    if (timer_timeout(TASK_1_ID))
    {
        /* task has wait long enough, it can run again */

        /* DO TASK 1 STUFF */
        printf("hello from task 1\n");

        /* Ask to wait for 150 ticks */
        timer_set_wait(TASK_1_ID, 150);
    }
}

/**task-2.c**/

/*TASK ID must be valid and unique in s_timer */
#define TASK_2_ID 1

void task_2()
{
    if (timer_timeout(TASK_2_ID))
    {
        /* task has wait long enough, it can run again */

        /* DO TASK 2 STUFF */
        printf("hello from task 2\n");

        /* Ask to wait for 250 ticks */
        timer_set_wait(TASK_2_ID, 250);
    }
}

并安排(这里是一个大词)任务:

/** main.c **/

int main()
{
    /* init the program, like set up the timer interruption */
    init() 

    /* do tasks, for ever*/
    while(1)
    {
        task_1();
        task_2();
    }
    return 0;
}

我认为我所描述的是一个不应该认真使用的蹩脚解决方案。

我给出的代码充满了问题,比如如果一个任务执行速度变慢会发生什么......

相反,您--可以-- 应该使用一些 RT 操作系统,例如 FreeRTOS,这对此类问题非常有帮助。

【讨论】:

  • 解决方案实际上非常聪明。唯一的问题是我可能会在其中执行无限量的任务,我需要大量修改它。
  • 操作系统(OSi?)对于我正在做的事情来说实际上相当繁重,因此最好忽略它们,即使使用它会容易得多。
  • “解决方案实际上非常聪明。”谢谢
  • “操作系统对于我正在做的事情来说实际上是相当沉重的,所以最好忽略它们”所以我说...... 5年前,现在我仍然没有操作系统,而且我经常错过了。
  • 我理解你的痛苦。但是对于我目前的项目,最好不要使用它。
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
相关资源
最近更新 更多