亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? yavrtos.dox

?? yavrtos,一款用于廣泛用于AVR單片機(jī)的RTOS,文件里是這款OS的源碼
?? DOX
?? 第 1 頁 / 共 5 頁
字號:
                lock_off(&porta_mutex);
                // Now, suspend this task for another 200 ticks
                wait_for_increment_of(&tick, 200);
        }
}

// This is our second task - blinking port A bit 1 once every 280 ticks
void blink2(void *p) {
        while (1) {
                // Obtain a lock on the port A mutex
                lock_on(&porta_mutex);
                // OK - port A is now all ours, so blink the LED
                PORTA ^= 0x02;
                // Release our hold on the port A mutex
                lock_off(&porta_mutex);
                // Now, suspend this task for another 280 ticks
                wait_for_increment_of(&tick, 280);
        }
}

// This is our idle task - the task that runs when all others are suspended.
// We sleep the CPU - the CPU will automatically awake when the tick interrupt occurs
void idle_task(void *p) {
        sleep_enable();
        sei();
        sleep_cpu();
        // This task cannot be stopped, so it is automatically re-started whenever it tries to exit
}

// This is a function that runs every tick interrupt - we use it to increment the tick semaphore value by one
uint8_t tick_interrupt() {
        increment_semaphore_by(&tick,1);
        // We want a task switch to ALWAYS occur - it is part of the definition of the tick interrupt!
        return 1;
}

// Setup the TIMER1_COMPA interrupt - it will be our tick interrupt
TASK_ISR(TIMER1_COMPA_vect, tick_interrupt())

// Our entry point
int main(void) {
        // Interrupts should remain disabled - they will be enabled as soon as the first task starts executing
        cli();
        // Set up port A for output
        DDRA = 0xFF;
        // Our idle task sleeps the CPU - set the sleep mode to IDLE, as we need the sleep to be
        // interruptable by the tick interrupt
        set_sleep_mode(SLEEP_MODE_IDLE);
        // Create our two tasks
        create_task(blink1, 0, 0, 55, 100, 0);
        create_task(blink2, 0, 0, 55, 100, 0);
        // Set up our TIMER1_COMPA interrupt to tick every 80,000 clock cycles
        TCCR1B = 0x0A;
        OCR1A = 9999;
        TIFR = _BV(OCF1A);
        TIMSK |= _BV(OCIE1A);
        // Start the RTOS - note that this function will never return
        task_switcher_start(idle_task, 0, 55, 55);
        return 0;
}
\endcode


*/


/**



\page howdoI How do I?

\section malloc How do I use malloc() and free() safely?

It depends on whether you intend to use malloc() or free() from within ISRs (which is highly
discouraged) or from within idle tasks (i.e. tasks with a zero priority). Note that
create_task() and reserve_task() can call malloc().

\subsection malloc-isr Using malloc() and free() when they are going to be used from within ISRs and/or idle tasks

If you are going to use malloc() or free() from within an ISR and/or an idle task, you will need to disable interrupts
either side of you call to malloc() and free()

\code
void proc() {
  int *data = 0;
  interrupt_store_t interrupts;

  interrupts = disable_interrupts();
  data = malloc(REQUIRED_INTS * sizeof(int));
  restore_interrupts(interrupts);
  ...
  interrupts = disable_interrupts();
  free(data);
  restore_interrupts(interrupts);
  ...
}
\endcode

The reason why we use the \c interrupt_store_t is because our \c proc() may have been called by another function that disabled interrupts for its own purposes, and it could be disastrous to unexpectedly enable interrupts on it.

We also want to disable interrupts for the shortest possible period of time, as disabling interrupts disables the all-important tick.

Note that interrupts will be disabled for the duration of the call to malloc() and free(). Depending on the algorithm used by
malloc() and free(), and depending on what your time margin for the launch of ISRs is, interrupts could be disabled for "too long". And note
that malloc() is called by reserve_task(), and can be called by create_task(), so using create_task() and reserve_task() in such time-critical
situations could break your application.

\subsection malloc-no-isr Using malloc() and free() when they are not going to be used from within ISRs or idle tasks

If you are not going to use malloc() or free() from within ISRs or idle tasks, then you can create a \ref mutex "mutex" for the
microcontroller's memory.

\code
mutex_t memory_mutex;

void proc() {
  int *data = 0;

  lock_on(&memory_mutex);
  data = malloc(REQUIRED_INTS * sizeof(int));
  lock_off(&memory_mutex);
  ...
  lock_on(&memory_mutex);
  free(data);
  lock_off(&memory_mutex);
  ...
}
\endcode

If you do this, then you \b must specify \c wait_for_mutexes in stop_task() when stopping any task that uses
the memory mutex. This is because stop_task() could be called when the task is in the middle of executing
malloc() or free(), and if malloc() or free() are not allowed to complete themselves, corruption of the tables
used by malloc() and free() could result.

Using a memory mutex, however, has the significant advantage that interrupts are only disabled for a very short period of time
during lock_on() and lock_off().

If you are using a mutex for the microcontrollers' memory, remember to use that mutex in all calls to
create_task() and reserve_task(). (If you haven't yet started the RTOS with task_switcher_start(), then
the \c memory_mutex argument to create_task() and reserve_task() will be ignored, and interrupts
will be disabled during the calls to malloc()).

\code
mutex_t memory_mutex;

void proc() {
  int *data = 0;

  lock_on(&memory_mutex);
  data = malloc(REQUIRED_INTS * sizeof(int));
  lock_off(&memory_mutex);
  ...
  // We must use the mutex in all calls to create_task() and reserve_task()!
  create_task(task2, 0, 0, 55, 20, &memory_mutex);
  ...
  lock_on(&memory_mutex);
  free(data);
  lock_off(&memory_mutex);
  ...
}
\endcode

\section how-write-isr How do I write my own ISR?

For instance, we will write an ISR for the INT0 interrupt.

\code
// Define the ISR prototype, so that the TASK_ISR() macro can reference our ISR function "int0_isr()"
uint8_t int0_isr();

// Set up the INT0 vector so that it calls the ISR
TASK_ISR(INT0_vect, int0_isr())

// Now, we can write the ISR function itself. It should return non-zero if a task switch should occur.
// It is recommended that it returns non-zero - the only time it would be safe for it to return zero
// would be if it didn't do anything to any task, semaphore, mailbox or mutex (i.e. if it didn't do anything
// that could un-suspend a suspended task).
uint8_t int0_isr() {
  ...
}
\endcode

Upon entry into the \c int0_isr function, interrupts will be disabled, and the system stack will be in use.

*/


/**



\page QandA Questions and Answers

\section qanda-int What happens if I disable interrupts, then suspend myself (e.g. by waiting on a semaphore)?

If you disable interrupts, then the task switcher cannot run, as it depends on the tick interrupt. However, if you then use an API call that can run the task switcher as a side-effect, the task switcher could decide to run a task that didn't disable interrupts Since the task switcher remembers which tasks have disabled interrupts and which tasks haven't, interrupts would be re-enabled.

However, the next time the task switcher chooses your task, it will re-disable interrupts before resuming your task. Indeed, it will disable interrupts before it even decides that your task is the next task that should run.

\section qanda-int2 Why would I want to disable interrupts anyway?

When interrupts are enabled, your task can be interrupted literally in the middle of a statement. If that statement was accessing a shared resource, then the state of that shared resource could change right in the middle of your statement. The only way to ensure that you are acting on a consistent shared resource is to disable interrupts as you are accessing it.

The classic example of this problem is a bank.

\code
int32_t balance = 80;

void deduct_task_1(void *p) {
  if (balance >= 20) {
    balance -= 20;
  }
}

void deduct_task_2(void *p) {
  if (balance >= 50) {
    balance -= 50;
  }
}
\endcode

Assuming that the two tasks are executing simultaneously, and \c deduct_task_1 is the first one to run. It will see that the balance is sufficient, and will execute the "balance -= 20" statement. What that statement actually means, of course, is "balance = balance - 20". In other words, "read the value of balance, subtract 20, and store the result back in balance".

The problem arises when the task is interrupted, for instance, between "subtract 20" and "store the result back in balance". When it has subtracted 20, the new value is 60, and it is prepared to store that result back. However, if the task is interrupted, and \c deduct_task_2 is run, it will put a value of 30 into balance. Then, when \c deduct_task_1 resumes, it will over-write the value of balance with 60, with the result that the customer has gained 50 cent.

The only way to fix this is to make sure that the two tasks cannot interrupt each other -

\code
int32_t balance = 80;

void deduct_task_1(void *p) {
  interrupt_store_t interrupts = disable_interrupts();
  if (balance >= 20) {
    balance -= 20;
  }
  restore_interrupts(interrupts);
}

void deduct_task_2(void *p) {
  interrupt_store_t interrupts = disable_interrupts();
  if (balance >= 50) {
    balance -= 50;
  }
  restore_interrupts(interrupts);
}
\endcode

You will notice that we disable interrupts before we check the customers balance - if we didn't, the balance could change between when we check it and when we do the deduction, and so we could end up giving the customer credit on their balance.

\section qanda-int3 Must I therefore disable interrupts every time I access a shared resource?

You can either disable interrupts, or create a \ref mutex "mutex" for the shared resource and lock on that whenever you access the resource. However, since mutexes are not available to ISRs, the only way to access a shared resource that is also used by an ISR is by disabling interrupts.

The only exception to this rule is if your C compiler compiles the statement that accesses the resource into a single CPU instruction. This can happen, but is rare.

Note that all YAVRTOS functions disable interrupts as appropriate, so if you are using \ref mailbox "mailboxes" or
\ref semaphore "semaphores" in an ISR, there is no need to worry about interrupts in your tasks when you are accessing those resources.

\section qanda-stop Why can a task only be stopped by a higher-priority task?

The only way that task A can know if it has stopped task B completely is if task A is a higher-priority task than task B. Why? Because a task C, of higher-priority than both A and B, could re-start task B as soon as it has died. But if task B is of lower priority than task A, task B will not be able to re-start until task A has finished processing the fact that task B has died.

(Therefore, it is in fact possible for a lower-priority task to stop a higher-priority task - it just isn't possible for that task to know when the higher-priority task has completely stopped. However, I think that is bad practice, so it is disabled in YAVRTOS).

\section qanda-pri Can I change the priority of a task?

No. This has to do with the stopping of tasks - if a task is being stopped by a higher-priority task, and it is re-started with an even higher priority, the task may get to start before the stopping task is informed that it has stopped.

\section qanda-sei When my ISR runs, interrupts are disabled - may I re-enable them?

Yes. If your ISR is interrupted by another ISR, the second ISR will continue to use the system stack. When the last ISR has completed, a task switch will be performed if any of the ISRs requested it.

\section qanda-cleanup What is the task cleanup function about?

The task cleanup procedure is called whenever a (non-zero-priority) task is stopped. A task is stopped by someone calling stop_task(), or when the task procedure finishes.

The task cleanup procedure should be used to release any resources that the task may have reserved. Since stop_task() may be called at any time, the task may have reserved resources (e.g. memory) that it would need to release before it goes away.

See task_stopper() for more information.

\section qanda-cleanup2 Can the task cleanup function be stopped?

No, though it is subject to the normal rules of the task scheduler.

\section qanda-task-inf Does a task have to have an infinite loop?

No - if a task returns, and it is a non-zero-priority task, it will be stopped. If it is a zero-priority "idle" task, it will be re-started.

\section qanda-cpuctx In task.h, what do the save_cpu_context() and restore_cpu_context() macros do?

These macros are the central part of a pre-emptive RTOS - what they do is save the state of the CPU to the stack, and restore it from the stack. So, when the CPU state is restored, the CPU is able to continue doing whatever it was doing as if it was never interrupted.

In save_cpu_context(), the R0 register is the first to be saved. Then the status register contents are copied to the R0 register, and interrupts are disabled. Then, the registers R1 to R31 are saved. Finally, R0 (i.e. the status register contents) is saved. Why do I do it this way? I want to disable interrupts as quickly as possible (otherwise, I could be interrupted in the middle of saving the CPU context to the stack, which would initiate another save of the CPU context to the stack, which could quickly overflow the stack). However, I also need to store the state of the global interrupts enabled flag in the status register. So I save R0 to the stack, then load the status register to R0, then disable interrupts, then save everything else.

In restore_cpu_context(), the R0 register (which contains the status register contents - including the global interrupt enable flag) is retrieved from the stack. Then the registers R31 to R1 are restored. Then R0 is copied into the status register - this may have the effect of re-enabling interrupts. Finally, the R0 register is retrieved from the stack.

\section qanda-saveint In task.h, what is "*(((uint8_t*)SP)+1) |= _BV(SREG_I);" about?

In a nutshell, that statement means "set the global interrupt enabled bit in the last byte on the stack".  The last byte to be saved to the stack is the status register - the one that contains the global interrupt enabled bit. So why do we set this bit? Because we want interrupts to be enabled when we restore the CPU context. Why? Because interrupts were enabled when the ISR started (otherwise it wouldn't have started!) and we want to restore the state of the interrupts when we are finished.

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
性做久久久久久久免费看| 日本久久精品电影| 精品一区二区三区免费播放| 三级久久三级久久| 五月天激情综合| 香蕉久久一区二区不卡无毒影院| 亚洲一区二区三区四区的| 亚洲精品精品亚洲| 亚洲综合激情小说| 午夜伦理一区二区| 美女网站一区二区| 国产一区二区日韩精品| 国产传媒久久文化传媒| 99视频精品在线| 一本色道久久综合亚洲91| 在线看国产日韩| 69久久99精品久久久久婷婷| 精品美女一区二区| 中文字幕高清一区| 伊人性伊人情综合网| 婷婷久久综合九色国产成人| 麻豆极品一区二区三区| 国产69精品久久777的优势| 99免费精品在线观看| 欧美午夜一区二区| 日韩欧美的一区二区| 国产日韩欧美精品综合| 亚洲欧美另类久久久精品| 亚洲成av人片在线| 国产综合久久久久影院| 不卡视频在线看| 欧美日韩国产一二三| 亚洲精品一区二区三区在线观看| 国产日产精品一区| 一区二区三区精品在线| 久久 天天综合| 99re热视频精品| 日韩视频一区二区三区在线播放| 久久婷婷国产综合精品青草| 成人免费一区二区三区在线观看| 亚洲高清免费在线| 国产成人亚洲综合a∨猫咪| 色视频一区二区| 欧美va亚洲va国产综合| 中文字幕亚洲一区二区av在线| 亚洲电影你懂得| 国产不卡高清在线观看视频| 欧美在线免费观看视频| 久久综合九色综合久久久精品综合| 国产精品免费视频观看| 日韩影院免费视频| 99re这里只有精品首页| 欧美成人精品福利| 伊人色综合久久天天人手人婷| 久久丁香综合五月国产三级网站| 国产mv日韩mv欧美| 日韩一级精品视频在线观看| 中文字幕亚洲精品在线观看| 精一区二区三区| 欧美在线观看一区二区| 欧美激情一区二区三区全黄| 婷婷中文字幕综合| 99国产精品久久久久久久久久 | 高清成人在线观看| 在线播放中文一区| 综合电影一区二区三区 | 欧美中文字幕亚洲一区二区va在线| 欧美大片顶级少妇| 亚洲高清免费观看| 91免费视频网| 中文字幕免费观看一区| 麻豆视频一区二区| 欧美喷潮久久久xxxxx| 国产精品国产三级国产普通话三级 | 成人av影院在线| 久久婷婷一区二区三区| 免费一区二区视频| 欧美蜜桃一区二区三区| 亚洲欧美另类小说视频| 成人小视频在线| 亚洲精品在线网站| 日韩av一级电影| 色婷婷av一区二区三区gif| 中文av字幕一区| 国产精品夜夜爽| 精品噜噜噜噜久久久久久久久试看 | 蜜臀av性久久久久蜜臀aⅴ| 欧美色国产精品| 亚洲综合一二区| 色狠狠色噜噜噜综合网| 亚洲天堂av老司机| 成人av网址在线| 中文在线一区二区| 国产成人超碰人人澡人人澡| 久久综合色综合88| 精品一区二区三区免费视频| 日韩欧美一级特黄在线播放| 天堂在线一区二区| 欧美精品国产精品| 日韩极品在线观看| 日韩一区二区在线免费观看| 日韩av电影天堂| 欧美电影精品一区二区| 精品一区二区三区视频 | 强制捆绑调教一区二区| 欧美另类久久久品| 日韩国产在线观看一区| 91精品国产麻豆国产自产在线 | 日本成人在线一区| 精品国产一区二区亚洲人成毛片| 麻豆精品国产91久久久久久| 日韩欧美电影在线| 国产精品自在欧美一区| 国产午夜亚洲精品羞羞网站| 成人天堂资源www在线| 亚洲欧美自拍偷拍色图| 色婷婷av一区| 五月天久久比比资源色| 日韩一区二区电影| 国产suv一区二区三区88区| 一区在线观看视频| 欧美亚洲国产bt| 免费观看一级欧美片| 欧美精品一区二区三区蜜桃| 丁香婷婷综合激情五月色| 亚洲视频电影在线| 欧美精品亚洲二区| 韩国v欧美v日本v亚洲v| 中国av一区二区三区| 在线免费不卡视频| 蜜桃视频一区二区| 国产精品成人一区二区艾草| 欧洲一区在线观看| 蜜桃久久久久久| 国产精品不卡一区| 欧美日韩久久一区| 国产一区二区导航在线播放| 国产精品第四页| 在线成人免费观看| 国产成人亚洲精品青草天美| 一区二区三区欧美久久| 精品欧美久久久| 91黄视频在线观看| 激情深爱一区二区| 一区二区三区在线视频观看58| 欧美一级二级三级乱码| 高清不卡一区二区| 日韩成人免费看| 中文字幕av在线一区二区三区| 欧美性一区二区| 国产福利一区二区| 五月综合激情网| 中文字幕成人av| 69av一区二区三区| 91小宝寻花一区二区三区| 日韩和欧美一区二区三区| 国产精品福利在线播放| 日韩视频中午一区| 欧洲亚洲国产日韩| 成人黄色在线视频| 美女视频黄免费的久久 | 国产乱一区二区| 亚洲成a人片综合在线| 国产午夜精品理论片a级大结局 | 亚洲国产精品成人综合色在线婷婷| 精品视频一区 二区 三区| 丁香一区二区三区| 精品一区二区国语对白| 亚洲欧美日韩一区二区| 久久九九99视频| 欧美大片一区二区三区| 欧美专区日韩专区| av一二三不卡影片| 国产一区 二区 三区一级| 亚洲电影激情视频网站| 亚洲天堂中文字幕| 国产视频一区二区三区在线观看| 欧美酷刑日本凌虐凌虐| 日本乱人伦一区| 99国产精品视频免费观看| 国产69精品久久777的优势| 久久爱另类一区二区小说| 亚洲成人综合视频| 一区二区三区欧美久久| 亚洲欧洲精品一区二区三区| 久久亚洲综合av| 精品奇米国产一区二区三区| 91精品国产丝袜白色高跟鞋| 欧美视频一区在线| 色综合久久久久久久久久久| jvid福利写真一区二区三区| 国产精一品亚洲二区在线视频| 久久99精品久久久| 九九视频精品免费| 极品美女销魂一区二区三区| 免费观看在线色综合| 免费三级欧美电影| 麻豆极品一区二区三区| 久久国产免费看| 国产一区二区三区日韩|