用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,但我相信这种解决方案也适用于不同的工具包,FPGAs。)
发布于 2017-02-16 13:40:50
TL;博士
使用微操作系统,比如FreeRTOS。
坏答案
如果您没有OS,没有任务转换,但是有外部计时器,您可以使用以下方法:
为硬件定时器启用中断,并管理由此插入驱动的计数器:
你应该有这样的
/**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,它在这类问题上非常有帮助。
https://stackoverflow.com/questions/42267901
复制相似问题