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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? task.h

?? yavrtos,一款用于廣泛用于AVR單片機的RTOS,文件里是這款OS的源碼
?? H
?? 第 1 頁 / 共 2 頁
字號:
/*
 * Copyright (C) 2007-2008 Chris O'Byrne
 *
 * This file is part of YAVRTOS (see http://www.chris.obyrne.com/yavrtos/)
 *
 * YAVROTS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * YAVROTS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with YAVROTS.  If not, see <http://www.gnu.org/licenses/>.
 *
 * The author can be contacted at <chris@obyrne.com>
 *
 * version 1.7, 2008 Mar 01
 */

#ifndef TASK_H_
#define TASK_H_

#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdint.h>
#include <stdlib.h>

/**
 * \brief Structure describing a semaphore
 *
 * \sa semaphore
 */
typedef struct semaphorestruct {
	/** \brief \internal The value of the semaphore
	 *
	 * If you do decide to read or write the value of the semaphore directly, keep in mind
	 * \li it is a 16-bit value, and so interrupts need to be disabled when reading/writing
	 * \li after writing, a yield() may need to be performed
	 */
	int16_t value;
} semaphore_t;

/**
 * \brief Structure describing mailboxes
 *
 * \sa mailbox
 */
typedef struct mbox_struct {
	/// \internal The address of the current mailbox data
	void *data;
	/// \internal Readers wait on this semaphore. This semaphore's value is the "version" of the mailbox data
	semaphore_t reading_semaphore;
	/// \internal Writers wait on this semaphore for readers to finish reading, or for readers to suspend themselves on the mailbox
	semaphore_t writing_semaphore;
} mailbox_t;

// mutexstruct is used in taskstruct, and taskstruct is used in mutexstruct!
struct mutexstruct;

/**
 * \brief Structure describing a task
 *
 * \sa task
 */
typedef struct taskstruct {
	/// \internal Pointer to the top of the task stack
	uint8_t *stack;
	/// \internal Length of the task stack
	uint16_t stacklen;
	/// \internal The stack pointer as at the last time this task was suspended
	uint8_t *sp;
	/// \internal The task priority
	uint8_t pri;
	/// \internal The function that performs the tasks' activities
	void (*proc)(void*);
	/// \internal The function to execute when the task is stopping
	void (*cleanup)();
	/// \internal The first mutex this task owns
	struct mutexstruct *owned_mutex;
	/// \internal The mailbox we are waiting on or reading from
	mailbox_t *waiting_on_mbox;
	/**
	 * \brief \internal The version of the mailbox that we are reading or waiting on
	 *
	 * If this value is greater than the mailbox version, then we are waiting, otherwise we are reading
	 */
	int16_t waiting_on_mbox_version;
	/// \internal The semaphore the task is waiting on
	semaphore_t *waiting_semaphore;
	/// \internal The value of the semaphore that the task is waiting on
	int16_t waiting_semaphore_min_value;
	/**
	 * \brief \internal Task status
	 *
	 * \sa taskstategroup
	 */
	uint8_t status;
	/// \internal Pointer to the next task in the list
	struct taskstruct *next;
} task_t;

/**
 * \brief A structure describing a mutex
 *
 * \sa mutex
 */
typedef struct mutexstruct {
	/// \internal The task that currently owns the mutex
	struct taskstruct *owner;
	/// \internal The semaphore that other tasks waiting to own the mutex will suspend themselves against
	semaphore_t notification;
	/// \internal The next mutex that is owned by this task - used to release mutexes owned by a stopping task
	struct mutexstruct *next;
} mutex_t;

/**
 * \ingroup task
 *
 * \brief The current task.
 *
 * This value may be used in stop_task() to stop the current task
 */
extern task_t *current_task;

/**
 * \ingroup task
 *
 * \brief Tasks are kept in a linked list in memory - this function reserves an "empty" task on that list, ready to be
 * subsequently utilised by a call to create_task().
 *
 * \attention reserve_task() calls malloc(), and disables interrupts during the call to malloc(). Therefore,
 * depending on the amount of time your malloc() algorithm takes, and depending on what your time margin for the
 * launch of ISRs is, reserve_task() could disable interrupts for "too long". See the description of the
 * \c memory_mutex argument, and \ref malloc
 *
 * The arguments are
 * \arg \c stacklen - the number of bytes to reserve for the task stack. Note that it must be long enough to hold a copy
 *     of the value of all 32 registers when a task switch occurs, and it needs a couple of extra bytes to handle
 *     interrupts, function calls etc.
 * \arg \c pri - the priority of the task. The highest-priority available task will "hog" the CPU. If the task has a priority
 *     of zero (an "idle" task), then it may not suspend itself on a mutex, semaphore or mailbox.
 * \arg \c memory_mutex - if not null, and if called from within a non-idle task, this mutex will be locked on to during the
 *		call to malloc(), otherwise interrupts will be disabled during the call to malloc() - see \ref malloc.
 */
task_t *reserve_task(uint16_t stacklen, uint8_t pri, mutex_t *memory_mutex);

/**
 * \ingroup task
 *
 * \brief Create a task, ready to be run.
 *
 * \attention create_task() can call malloc(), and disables interrupts during any call to malloc(). Therefore,
 * depending on the amount of time your malloc() algorithm takes, and depending on what your time margin for the
 * launch of ISRs is, create_task() could disable interrupts for "too long". See the description of the
 * \c memory_mutex argument, and \ref malloc
 *
 * The arguments are
 * <ul>
 * <li> \c proc - this is the task function. Upon entry, interrupts will be enabled, and the value of the argument will
 *			be that of \c init_data. This function does not need to
 *			contain an infinite loop - if it returns (and if the priority is greater than zero), a stop will be
 *			performed on the task.</li>
 * <li> \c cleanup - this is the task cleanup function, which will be called as the task is dying. May be null if the task
 *			doesn't need to clean up after itself. See task_stopper()</li>
 * <li> \c init_data - this is the value that will be given in the argument to \c proc when it starts</li>
 * <li> \c stacklen - the number of bytes to reserve for the task stack. Note that it must be long enough to hold a copy
 *     of the value of all 32 registers when a task switch occurs, and it needs a couple of extra bytes to handle
 *     interrupts, function calls etc.</li>
 * <li> \c pri - the priority of the task. The highest-priority available task will "hog" the CPU. If the task has a priority
 *     of zero (an "idle" task), then it may not suspend itself on a mutex, semaphore or mailbox, and it may not be stopped.</li>
 * <li> \c memory_mutex - if not null, and if called from within a non-idle task, this mutex will be locked on to during the
 *		call to malloc(), otherwise interrupts will be disabled during the call to malloc() - see \ref malloc</li>
 * </ul>
 *
 * This function will scan through the task list in memory, looking for one that is not being used with a matching pri and a stacklen
 * that is at least as large as that required. If it cannot find such a task, it will create a brand new one. See reserve_task()
 */
task_t *create_task(void (*proc)(void*), void (*cleanup)(), void *init_data, uint16_t stacklen, uint8_t pri, mutex_t *memory_mutex);

/**
 * \ingroup task
 *
 * \brief Stop a task.
 *
 * The arguments are
 * \arg \c t the task to stop
 * \arg \c wait_for_mutexes - if not zero, the task will not be stopped until it has released all of its mutexes. If zero,
 *			then the tasks will stop immediately. Note that if you are using a memory mutex, you \b must set
 *			\c wait_for_mutexes when stopping any task that uses the memory mutex - see \ref malloc
 *
 * This function can be called by the current task (stop_task(current_task, ...)), or by a higher-priority task, or by an ISR,
 * and may be called on any non-zero-priority task.
 *
 * If this function is called by the current task, and \c wait_for_mutexes isn't set, then the "cleaning up" of the task
 * (task_stopper()) will start executing immediately - i.e. the stop_task(current_task, 0) call won't "return". If
 * \c wait_for_mutexes is set, then the lock_off() that releases the tasks' last mutex won't return - the task_stopper()
 * will run instead.
 *
 * If this function is called by a higher priority task, then it will not return until the task in question has
 * completely stopped executing.
 *
 * If this function is called from within an ISR, it will return immediately.
 *
 * A return value of -1 means that the calling task doesn't have the required permission. A return value of -2 means
 * that an attempt was made to stop a zero-priority task. A return value of zero indicates success, and a return value of
 * 1 means that the task was already stopped.
 *
 * See task_stopper() for a description of what happens to the task that is being stopped.
 */
int8_t stop_task(task_t *t, uint8_t wait_for_mutexes);

/**
 * \ingroup task
 *
 * \brief Stop executing the current task and try and execute a higher-priority task or another task of the same priority.
 *
 * Note that all API calls that could theoretically cause a higher-priority task to be re-enabled will
 * call yield(), which will cause an automatic and immediate task switch to that higher-priority task. (This
 * also means that if there is another task of the same priority that hasn't been disabled, all such API
 * calls will cause a task switch to that task).
 *
 * Obviously this function can only be called by tasks, and it will "return" the next time it is the turn of the
 * current task to execute.
 */
void yield() __attribute__ ((naked));

/**
 * \ingroup mutex
 *
 * \brief Lock on a mutex.
 *
 * The return value is zero for success.
 *
 * Since the task may be suspended while waiting for another task to release the mutex, this function may only be
 * called by tasks with a non-zero priority.
 */
uint8_t lock_on(mutex_t *m);

/**
 * \ingroup mutex
 *
 * \brief Unlock a mutex.
 *
 * This function can only usefully be called by the task that locked the mutex in the first place, and it
 * may end up yielding control to a task that is waiting on the mutex. The return value is zero for success.
 *
 * Note that if someone has called stop_task() on this task with the \c wait_for_mutexes parameter set, and if the
 * call to this function is the one that releases the tasks' last mutex, then this function won't "return" - the
 * task_stopper() will run on this task instead.
 */
uint8_t lock_off(mutex_t *m);

/**
 * \ingroup mailbox
 *
 * \brief Get the current version of a mailbox
 *
 * This function can be called by an ISR, by any task, or even before the RTOS starts
 */
int16_t get_current_mbox_version(mailbox_t *mbox);

/**
 * \ingroup mailbox
 *
 * \brief Wait for a mailbox to reach at least a certain version, and then start reading from it
 *
 * \attention It is \b vital that release_mbox_read() be called to release the mailbox for other tasks to write to
 *		it when the calling task has finished reading the mailbox data
 *
 * The arguments are
 * \arg \c mbox - the mailbox to read from
 * \arg \c version - the minimum version of the mailbox that we require. Note that the version of the mailbox actually read
 *			will be written to this address
 *
 * The return value is a pointer to the mailbox data. Note that a zero return value does not mean that the mailbox
 * read failed - it means that the mailbox was empty - and hence release_mbox_read() must still be called.
 *
 * Since this function can cause a suspension (i.e. if the mailbox hasn't reached the specified version), it can only be
 * called from a task with a non-zero priority
 */
void *read_mbox_min_version(mailbox_t *mbox, int16_t *version);

/**
 * \ingroup mailbox
 *
 * \brief Read a mailbox
 *
 * This function reads a mailbox regardless of the version of the mailbox.
 *
 * \attention It is \b vital that release_mbox_read() be called to release the mailbox for other tasks to write to
 *		it when the calling task has finished reading the mailbox data
 *
 * The arguments are
 * \arg \c mbox - the mailbox to read
 * \arg \c version - if not null, the version of the mailbox will be written to this address
 *
 * The return value is a pointer to the mailbox data. Note that a zero return value does not mean that the mailbox
 * read failed - it means that the mailbox was empty - and hence release_mbox_read() must still be called.
 *
 * Since this function can cause a suspension (i.e. if the mailbox hasn't reached the specified version), it can only be
 * called from a task with a non-zero priority
 */
void *read_mbox(mailbox_t *mbox, int16_t *version);

/**
 * \ingroup mailbox
 *
 * \brief Function to call when finished reading from a mailbox
 *
 * Since tasks are not allowed to write to a mailbox while there are other tasks reading from it, this function
 * \b must be called when a task has finished reading from a mailbox - i.e. it must be called after every call to
 * read_mbox() or read_mbox_min_version()
 *
 * Since a task can only read one mailbox at a time, there are no arguments to this function. The return value is
 * the mailbox that the task was reading from, or zero if it was not reading from any mailbox.
 *
 * Note that calling this function may cause a higher-prioroty task that is waiting to write to the mailbox to be
 * scheduled.
 */
mailbox_t *release_mbox_read();

/**
 * \ingroup mailbox
 *
 * \brief Initialise a mailbox - this \b must be called on every mailbox before it is used
 *
 * The arguments are
 * \arg \c mbox - the mailbox to initialise
 * \arg \c data - the pointer to the mailbox data. This is the value that will be returned by read_mbox() and
 *			read_mbox_min_version(). It is acceptable to set this value to zero - though callers to read_mbox()
 *			and read_mbox_min_version() would need to be aware that the return value could be zero.
 * \arg \c version - the initial version of the mailbox
 */
void initialise_mbox(mailbox_t *mbox, void *data, const int16_t version);

/**
 * \ingroup mailbox
 *
 * \brief Write to a mailbox
 *
 * A write to a mailbox will
 * \li wait for all tasks that are reading the mailbox to call release_mbox_read()
 * \li if \c wait_for_receivers is not zero, it will wait until there are at least that many tasks that have suspended themselves
 *		on read_mbox_min_version() while waiting for fresh data to be put into this mailbox. Otherwise, the data that is put into
 *		the mailbox might end up not being picked up by any task (e.g. if another write is made to the mailbox before
 *		any task attempts to read from it, that second write will over-write what is put into the mailbox by this function call)
 * \li then, the mailbox data will be updated, and the version will be incremented by one
 * \li if there are any higher-priority tasks suspended on read_mbox_min_version(), they will start executing

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品伊人色| 国产成人在线影院| 国产日产亚洲精品系列| 欧美色综合网站| 成人动漫av在线| 国产一区不卡精品| 国产精品一区二区黑丝| 在线观看91精品国产麻豆| 在线观看91视频| 欧美在线小视频| 中文字幕成人在线观看| 亚洲精品视频在线观看网站| 1024成人网| 亚洲在线视频网站| 亚洲国产美女搞黄色| 午夜欧美视频在线观看| 美腿丝袜亚洲色图| 精品一区在线看| 国产成人精品综合在线观看| 精品久久久久一区| 久久久综合网站| 国产午夜精品久久久久久免费视| 综合亚洲深深色噜噜狠狠网站| 亚洲精品乱码久久久久久久久 | 久久福利资源站| 成人免费观看视频| 欧美精品在线观看一区二区| 一区二区在线观看视频| 91女神在线视频| 91精品国产高清一区二区三区| 精品国产一区二区三区久久影院| 中文字幕一区二区三区av| 丰满少妇在线播放bd日韩电影| 欧美日韩一区三区四区| 国产无一区二区| 国产美女在线精品| 国产欧美精品区一区二区三区| 国产成人亚洲精品狼色在线| 国产精品乱人伦一区二区| 日韩电影一区二区三区四区| 成人午夜激情影院| 自拍偷拍亚洲综合| 91蜜桃免费观看视频| 一区二区三区影院| 福利一区福利二区| 亚洲欧美乱综合| 风流少妇一区二区| 亚洲欧美激情插 | 久久久久久免费网| av中文字幕不卡| 26uuuu精品一区二区| 午夜私人影院久久久久| 欧美剧在线免费观看网站| 伦理电影国产精品| 国产精品久久福利| 成人一道本在线| 亚洲电影在线免费观看| 日韩精品一区二区三区在线播放 | 欧美一级一级性生活免费录像| 天天综合色天天| 久久久亚洲精品石原莉奈| 99re这里只有精品视频首页| 国产日韩欧美亚洲| 一本色道久久综合亚洲91| 欧美激情综合在线| 欧美日韩免费观看一区二区三区| 久久日韩粉嫩一区二区三区| 99精品黄色片免费大全| 日本va欧美va瓶| 91精品免费在线| 久久99国产精品久久| 亚洲精品va在线观看| 日韩精品在线一区| 欧美视频一区二区在线观看| 国产剧情一区二区| 日本亚洲天堂网| 亚洲欧洲综合另类| 久久久一区二区三区| 欧美人与禽zozo性伦| jlzzjlzz亚洲日本少妇| 久久精品99国产精品日本| 一区二区三区欧美激情| 国产色爱av资源综合区| 欧美精品第1页| 在线亚洲+欧美+日本专区| 国产精品亚洲一区二区三区在线| 日韩av网站免费在线| 亚洲男同性恋视频| 国产欧美一区二区精品性色超碰| 欧美一区二区三区视频免费| 欧美在线综合视频| 成人高清视频免费观看| 国产一本一道久久香蕉| 蜜臀久久久久久久| 亚洲国产另类精品专区| 成人免费一区二区三区视频| 国产欧美一区在线| 久久久www免费人成精品| 精品国产91乱码一区二区三区| 欧美日韩成人综合在线一区二区 | 成人丝袜高跟foot| 国产精品一二一区| 国产成人亚洲综合a∨婷婷| 国产伦精一区二区三区| 国内精品免费在线观看| 亚洲视频一二区| 国产精品不卡视频| 成人免费在线观看入口| 亚洲欧美在线另类| 中文字幕中文字幕一区| 综合色中文字幕| 亚洲免费在线观看| 亚洲精品ww久久久久久p站| 亚洲品质自拍视频| 亚洲国产精品欧美一二99| 亚洲黄色片在线观看| 亚洲欧美一区二区不卡| 亚洲综合在线观看视频| 亚洲成人一区在线| 中文字幕成人在线观看| 国产精品久久久久久久久晋中 | 26uuu色噜噜精品一区二区| 久久久久高清精品| 精品欧美一区二区三区精品久久| 欧美成人一级视频| 久久久久久综合| 1024成人网色www| 亚洲第一福利视频在线| 免费高清在线一区| 国产成人久久精品77777最新版本| 国产99久久久国产精品免费看| 99久久精品免费看国产| 欧美老年两性高潮| 久久午夜国产精品| 亚洲免费观看高清在线观看| 日韩电影在线观看电影| 国产精品资源在线观看| 91丨九色丨黑人外教| 欧美精品一卡两卡| 久久这里只有精品首页| 最新中文字幕一区二区三区| 午夜欧美一区二区三区在线播放| 精品一区二区三区免费视频| 成人一区在线观看| 欧美久久婷婷综合色| 久久久精品2019中文字幕之3| 亚洲女同一区二区| 国产在线精品一区二区三区不卡| 成人久久视频在线观看| 欧美日韩成人高清| 欧美国产97人人爽人人喊| 午夜精品久久久久久久久久 | 久久精品国产99| 91原创在线视频| 欧美精品一区二区三区一线天视频| 国产精品午夜在线观看| 亚洲成av人片www| 狠狠色丁香久久婷婷综合_中| 99久久久久久| 精品sm捆绑视频| 亚洲一区免费观看| 成人一区二区三区视频在线观看| 91精品一区二区三区久久久久久 | 色哟哟国产精品免费观看| 日韩一区二区不卡| 欧美欧美午夜aⅴ在线观看| 国产精品久久久久久亚洲毛片| 日韩高清在线一区| 99国产精品久久久久久久久久久| 日韩免费性生活视频播放| 亚洲综合精品自拍| av午夜精品一区二区三区| 日韩精品在线看片z| 视频在线观看一区| 韩国av一区二区三区| 欧美日本在线观看| 亚洲女同女同女同女同女同69| 国产精品一区二区久久不卡| 日韩免费一区二区| 青青青伊人色综合久久| 欧美日韩激情一区二区| 樱桃视频在线观看一区| caoporen国产精品视频| 久久久久9999亚洲精品| 精品一区二区免费| 欧美成人r级一区二区三区| 午夜精品福利一区二区蜜股av| 91浏览器入口在线观看| 国产日韩欧美综合一区| 国产成人av影院| 日本一区二区久久| 99久久综合国产精品| 中文在线一区二区| 99久久777色| 一区二区三区中文免费| 在线这里只有精品| 久久久久久久久岛国免费| 国内精品国产成人国产三级粉色| 亚洲精品一区二区三区福利| 九九精品一区二区|