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

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

?? task.h

?? yavrtos,一款用于廣泛用于AVR單片機(jī)的RTOS,文件里是這款OS的源碼
?? H
?? 第 1 頁 / 共 2 頁
字號:
 * \li if \c wait_for_empty_nullify is not zero, the function will not return until all tasks that had been suspended on
 *		read_mbox_min_version() have called release_mbox_read().
 * \li if \c wait_for_empty_nullify is greater than one, a new version of the mailbox data, containing a null pointer, will be
 *		published
 * 
 * If the task that writes to the mailbox can be stopped with stop_task(), then you could end up in a situation where the memory
 * location of the task data goes out of scope while the mailbox is being read. If this is a possibility, then it is recommended
 * that a \ref mutex "mutex" be created for the mailbox, that it be locked on to while the mailbox is being written to, that the
 * task only ever be stopped with the \c wait_for_mutexes parameter of stop_task() set, and that
 * \c wait_for_empty_nullify be set to at least one (it would need to be set at two if there are more than one tasks that could
 * read from the mailbox).
 *
 * The arguments are
 * <ul>
 * <li> \c mbox - the mailbox to write to</li>
 * <li> \c data - the pointer to the mailbox data. This is the value that will be returned by read_mbox() and
 *			read_mbox_min_version(), so it is vital that it points to valid data for the lifetime of this particular
 *			version of the mailbox.</li>
 * <li> \c wait_for_receivers - if non-zero, the write to the mailbox will not occur until there are at least
 *			\c wait_for_receivers task(s) waiting to read data from the mailbox. This could be used if it is
 *			vital that at least a specified number of
 *			receiving task(s) receive the information - it would give the receiving task(s) a chance to initialise</li>
 * <li> \c wait_for_empty_nullify
 *			<ul>
 * 			<li>if greater than zero, the function will not return until all tasks that were waiting to read the
 *			mailbox have done so. This could be used if it is vital that the sender knows that all messages have been received by
 *			the receiving task(s).</li>
 *			<li>if greater than one, the mailbox data will be set to null when all the tasks that were waiting to
 *			read the mailbox have done so (which means that subsequent reads of the mailbox will return a null pointer),
 *			so the data in the mailbox data buffer can safely be changed</li>
 *			</ul>
 * </ul>
 *
 * Since this function can cause a task suspension, it can only be called from a task with a non-zero priority
 */
void write_mbox(mailbox_t *mbox, void *data, uint8_t wait_for_receivers, uint8_t wait_for_empty_nullify);

/**
 * \ingroup mailbox
 *
 * \brief Attempt to write to a mailbox
 *
 * This function will attempt to write to a mailbox - if the mailbox is being read, and is therefore unavailable for writing
 * to as per the rules of mailboxes, this function will return
 * immediately without having written anything to the mailbox.
 *
 * The arguments are -
 * \arg \c mbox - the mailbox to write to
 * \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().
 *
 * The return value is zero on success
 *
 * Since this function will never cause a task suspension, it can be called from an ISR, from the idle task, or from anywhere
 * else in the application. Also, if this function is called from within a task, and if the task is potentially stoppable
 * by another task using stop_task() on it, then it is important that the memory location pointed to by \c data doesn't
 * go out of scope when the task is stopped.
 */
int8_t write_mbox_now(mailbox_t *mbox, void *data);

/**
 * \ingroup mailbox
 *
 * \brief Wait for a task to be suspended while trying to read from a mailbox
 *
 * This function will suspend the caller until another task is suspended while calling read_mbox_min_version(). This could
 * be used to give a task that needs to read the mailbox a chance to initialise.
 */
void wait_for_receiver(mailbox_t *mbox);

/**
 * \ingroup semaphore
 *
 * \brief Wait for a semaphore to reach at least a particular value.
 *
 * Since the calling task could be suspended, this can only be called by a task with a non-zero priority
 */
uint8_t wait_for_min_value(semaphore_t *s, int16_t value);

/**
 * \ingroup semaphore
 *
 * \brief Wait for a semaphore to increment its value by a certain amount
 *
 * The arguments are
 * \arg \c p - the semaphore to wait on
 * \arg \c amount - the amount by which the semaphore should increment before returning. Note that semaphore
 *			values are actually signed 16-bit numbers, so the maximum value for this argument is about 32,000
 *
 * Since the calling task could be suspended, this can only be called by a task with a non-zero priority
 */
uint8_t wait_for_increment_of(semaphore_t *p, uint16_t amount);

/**
 * \ingroup semaphore
 *
 * \brief Get the current value of a semaphore
 *
 * This function may be called anywhere
 */
int16_t get_semaphore_value(semaphore_t *s);

/**
 * \ingroup semaphore
 *
 * \brief Increment the value of a semaphore by the given amount.
 *
 * The arguments are
 * \arg \c s - the semaphore to increment
 * \arg \c amount - the amount by which the semaphore should be incremented. Note that semaphore
 *			values are actually signed 16-bit numbers, so the maximum value for this argument is about 32,000
 *
 * This may be called by any task, by an ISR, or even before the task
 * system is running.
 *
 * When called from a task, this function may end up yielding control to a higher-priority task that is waiting on the
 * semaphore.
 */
void increment_semaphore_by(semaphore_t *s, uint16_t amount);

/**
 * \ingroup task
 *
 * \brief Start the whole process running.
 *
 * Note that this method will never return. The arguments are
 * \arg \c idle - the "idle" function (the function to execute when we have nothing else to do)
 * \arg \c idle_data - the value of the argument to \c idle when it starts
 * \arg \c idle_stacklen - the length of the stack for the "idle" function - see create_task()
 * \arg \c system_stacklen - the length of the system stack - this is the stack that will be in use during all ISRs
 *
 * A recommended idle task is -
 * \code
 * void idle_task() {
 *   set_sleep_mode(SLEEP_MODE_IDLE);
 *   sleep_enable();
 *   sei();
 *   sleep_cpu();
 * }
 * \endcode
 *
 * See \ref Example "the example application" for an example of how to start the task switcher.
 *
 * Note that, if you are using the TASK_ISR() macro to give your ISRs access to the system stack (and you should!),
 * then all interrupts must remain disabled right up until this function is called. Interrupts will be enabled as soon
 * as the first task switch starts.
 */
void task_switcher_start(void (*idle)(void*), void *idle_data, uint16_t idle_stacklen, uint16_t system_stacklen) __attribute__ ((naked));


/**
 * \ingroup task
 *
 * \brief A flag indicating whether interrupts were enabled - used by disable_interrupts() and restore_interrupts()
 */
#define interrupt_store_t uint8_t

/**
 * \ingroup task
 *
 * \brief Disable interrupts system-wide.
 *
 * Returns a value which is non-zero if interrupts were enabled. Can be called
 * from anywhere.
 */
interrupt_store_t disable_interrupts();

/**
 * \ingroup task
 *
 * \brief Restore the state of the system-wide interrupts.
 *
 * A non-zero argument enables interrupts. Can be called from
 * anywhere.
 */
void restore_interrupts(interrupt_store_t interrupts);

/*
 * Everything below here is for the benefit of the TICK_ISR(vector) and TASK_ISR(vector,proc) macros
 */

/**
 * \brief \internal Structure used by the system to hold the system stack, and a flag indicating whether an ISR is currently
 * being executed.
 */
struct system_struct {
	/// non-zero if we are executing an ISR. Also, bit 1 is set if a task switch is required.
	uint8_t interrupted_task;
	/// The top of the system stack
	uint8_t *stack_top;
};

/**
 * \brief \internal The system_struct used to hold the system stack and a flag indicating whether an ISR is currently being
 * executed
 */
extern struct system_struct system;

/**
 * \brief \internal Save the CPU context to the stack, and disable interrupts
 */
#define save_cpu_context() __asm__ volatile( \
		"push  r0\n in r0, 0x3f\n cli\n" \
		"push  r1\n push  r2\n push  r3\n push  r4\n push  r5\n push  r6\n push  r7\n" \
		"push  r8\n push  r9\n push r10\n push r11\n push r12\n push r13\n push r14\n push r15\n" \
		"push r16\n push r17\n push r18\n push r19\n push r20\n push r21\n push r22\n push r23\n" \
		"push r24\n push r25\n push r26\n push r27\n push r28\n push r29\n push r30\n push r31\n" \
		"push  r0\n" ::)

/**
 * \brief \internal Restore the CPU context from the stack, possibly re-enabling interrupts
 */
#define restore_cpu_context() __asm__ volatile ( \
		"pop r0\n" \
		"pop r31\n pop r30\n pop r29\n pop r28\n pop r27\n pop r26\n pop r25\n pop r24\n" \
		"pop r23\n pop r22\n pop r21\n pop r20\n pop r19\n pop r18\n pop r17\n pop r16\n" \
		"pop r15\n pop r14\n pop r13\n pop r12\n pop r11\n pop r10\n pop  r9\n pop  r8\n" \
		"pop  r7\n pop  r6\n pop  r5\n pop  r4\n pop  r3\n pop  r2\n pop  r1\n out 0x3f, r0\n pop  r0\n" ::)

// The all-important task switch function
void switch_task() __attribute__ ((naked));

/**
 * \ingroup isr
 *
 * \brief The macro for ISRs
 *
 * The arguments are
 * \arg \c vector the ISR vector
 * \arg \c do_task_switch something that evaluates non-zero if the ISR should trigger a task switch. This
 * 		could be a constant, a function call, a macro, anything. Note that the tick interrupt \b must,
 * 		by definition, trigger a task switch. It is highly recommended that this macro always evaluates
 * 		to non-zero - the only time where it would be safe for it to evaluate to zero is if it does
 * 		absolutely nothing to any task, semaphore, mailbox or mutex (i.e. if it doesn't do anything that
 * 		could un-suspend a suspended task).
 *
 * See \ref Example "the example application" and \ref how-write-isr "how do I write an ISR" for
 * examples of usage.
 *
 * The WinAVR&tm; ISR() macro can also be used to define ISRs - however, when using ISR() as opposed to
 * TASK_ISR(), you cannot make use of any YAVRTOS API call from within your ISR, and your ISR will not
 * (necessarily) be using the system stack.
 *
 * Taking this macro apart line-by-line, we have
 *
 * \code
 * // The standard way of calling an ISR
 * void vector(void) __attribute__ ((signal,naked,__INTR_ATTRS));
 * // The ISR itself
 * void vector(void) {
 * 	// Save the entire CPU context to the stack (which could be a task stack or the system stack)
 * 	save_cpu_context();
 * 	// Global interrupts were enabled just before this ISR was launched (otherwise it would not have
 * 	// launched), and are disabled upon entry into the ISR. Set the interrupt enable bit at the location of
 * 	// the saved status register on the saved stack so that when we restore the CPU context, interrupts will
 * 	// be re-enabled.
 * 	*(((uint8_t*)SP)+1) |= _BV(SREG_I);
 * 	// Now, we have either interrupted a task or interrupted another ISR. system.interrupted_task will
 * 	// be non-zero if a task has already been interrupted - i.e. if we have interrupted an ISR
 * 	// Note that task_switch() also sets system.interrupted_task - any ISRs that manage to run during
 * 	// the brief period when task_switch() enables interrupts should not subsequently run task_switch()!
 * 	if (system.interrupted_task) { // We have interrupted an ISR (or we have interrupted task_switch())
 * 		// Execute the macro to see if we should do a task switch
 * 		if (do_task_switch) {
 * 			// The macro may have enabled interrupts - disable them again
 * 			cli();
 * 			// Set bit 1 of system.interrupted_task - the bit that signals that a task switch is
 * 			// required. We don't do the task switch just yet, as we have interrupted another ISR,
 * 			// so we need to return to that ISR first. The ISR that interrupted the task will be the one
 * 			// to actually perform the task switch (see below)
 * 			// If we have actually interrupted task_switch(), then setting bit 1 of system.interrupted_task
 * 			// will have no effect - but we were doing a task switch anyway!
 * 			system.interrupted_task = 3;
 * 		} else {
 * 			// Task switch not required (this time). Make sure that interrupts are still disabled
 * 			cli();
 * 		}
 * 	} else { // We have interrupted a task
 * 		// Save the stack pointer
 * 		current_task->sp = (uint8_t *)SP;
 * 		// Switch to the system stack
 * 		SP = (uint16_t) system.stack_top;
 * 		// Set the system.interrupted_task so that subsequent ISRs will know that they have interrupted
 * 		// an ISR, not a task. This has the side-effect of disabling switch_task() - all API calls check
 * 		// system.interrupted_task and do NOT perform a task switch if it is non-zero.
 * 		system.interrupted_task = 1;
 * 		// Execute the macro and see if we should do a task switch
 * 		if (do_task_switch) {
 * 			// The macro could have enabled interrupts - disable them
 * 			cli();
 * 			// Signal to ourselves that we need a task switch - bit 1 of system.interrupted_task is set
 * 			// when a task switch is required
 * 			system.interrupted_task = 3;
 * 		} else {
 * 			// Make sure that interrupts are disabled
 * 			cli();
 * 		}
 * 		// At this point, any ISRs that interrupted us have finished.
 * 		// Now, if a task switch is required, perform it!
 * 		if (system.interrupted_task & 2) {
 * 			// switch_task() will (eventually) reset system.interrupted_task, and never "returns"
 * 			switch_task();
 * 		}
 * 		// A task switch is not required - restore the stack pointer so that we return to the task
 * 		SP = (uint16_t) current_task->sp;
 * 		// We are about to return to the task - reset system.interrupted_task
 * 		system.interrupted_task = 0;
 * 	}
 * 	// Return to whatever we were doing before this ISR was called
 * 	restore_cpu_context();
 * 	__asm__ volatile ("ret" ::);
 * }
 * \endcode
 */
#ifdef DOXYGEN
#define TASK_ISR(vector, do_task_switch)
#else
#define TASK_ISR(vector,do_task_switch) \
void vector(void) __attribute__ ((signal,naked,__INTR_ATTRS)); \
void vector(void) { \
	save_cpu_context(); \
	*(((uint8_t*)SP)+1) |= _BV(SREG_I); \
	if (system.interrupted_task) { \
		if (do_task_switch) { \
			cli(); \
			system.interrupted_task = 3; \
		} else { \
			cli(); \
		} \
	} else { \
		current_task->sp = (uint8_t *)SP; \
		SP = (uint16_t) system.stack_top; \
		system.interrupted_task = 1; \
		if (do_task_switch) { \
			cli(); \
			system.interrupted_task = 3; \
		} else { \
			cli(); \
		} \
		if (system.interrupted_task & 2) { \
			switch_task(); \
		} \
		SP = (uint16_t) current_task->sp; \
		system.interrupted_task = 0; \
	} \
	restore_cpu_context(); \
	__asm__ volatile ("ret" ::); \
}
#endif /* DOXYGEN */

#endif /*TASK_H_*/

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久久不卡影院| 一本到一区二区三区| 欧美日韩五月天| 亚洲黄色在线视频| 欧美婷婷六月丁香综合色| 一区二区三区精品视频在线| 色悠悠久久综合| 偷拍与自拍一区| 欧美一级理论片| 国产成人精品综合在线观看| 中文字幕一区日韩精品欧美| 99国产精品视频免费观看| 一区二区三区中文免费| 欧美色老头old∨ideo| 日本亚洲电影天堂| 日本一区二区三区在线不卡 | 久久综合成人精品亚洲另类欧美| 国产福利精品导航| 亚洲一区二区在线观看视频| 91麻豆精品国产自产在线观看一区| 精品亚洲国内自在自线福利| 国产精品免费看片| 欧美日韩视频在线第一区| 丝袜亚洲另类丝袜在线| 久久久久国产精品麻豆ai换脸| 色综合夜色一区| 美国三级日本三级久久99| 久久麻豆一区二区| 欧美午夜片在线观看| 精品一区二区三区日韩| 国产精品午夜久久| 欧美视频日韩视频在线观看| 久久99热99| 亚洲午夜国产一区99re久久| 久久新电视剧免费观看| 色一区在线观看| 国产一区二区三区电影在线观看| 亚洲欧美日韩中文播放| 精品国产伦理网| 欧美亚洲精品一区| 成人av网站在线| 蜜桃精品视频在线| 亚洲精品乱码久久久久久久久| 日韩一区二区三区在线观看| 色综合久久综合中文综合网| 国产最新精品精品你懂的| 亚洲国产综合色| 一区视频在线播放| 久久久久久久久久久电影| 欧美一区二区三区在| 91蜜桃网址入口| 国产成人精品免费| 麻豆国产精品一区二区三区| 亚洲激情图片一区| 国产精品免费久久| 亚洲精品一区二区三区精华液| 欧美精品1区2区| 在线观看日韩一区| 99在线视频精品| 懂色av中文字幕一区二区三区| 蜜桃免费网站一区二区三区| 天天影视涩香欲综合网| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆 | 久久久久久久久久久久久久久99| 欧美精品777| 欧美精品精品一区| 欧美性xxxxx极品少妇| 91视频精品在这里| www.久久久久久久久| 成人深夜视频在线观看| 国产美女主播视频一区| 极品少妇xxxx偷拍精品少妇| 日本视频一区二区三区| 日韩一区精品字幕| 天天色天天操综合| 日韩电影免费在线观看网站| 亚洲福中文字幕伊人影院| 亚洲自拍偷拍av| 亚洲最色的网站| 亚洲国产精品精华液网站| 一区二区三区蜜桃| 亚洲成在线观看| 亚洲成av人在线观看| 亚洲bt欧美bt精品777| 婷婷综合久久一区二区三区| 日韩精品视频网站| 日本不卡视频在线| 久热成人在线视频| 国产精品一区二区在线观看不卡| 国产在线麻豆精品观看| 成人毛片老司机大片| 色一情一伦一子一伦一区| 欧美日韩国产电影| 精品日韩在线观看| 中文字幕精品一区二区精品绿巨人 | 日本道色综合久久| 欧美日韩国产精选| 日韩美女一区二区三区四区| 精品福利一区二区三区| 国产精品视频免费看| 亚洲精品日韩综合观看成人91| 午夜不卡在线视频| 韩国女主播一区| 91在线视频观看| 欧美日韩精品欧美日韩精品 | 天堂精品中文字幕在线| 国产真实乱对白精彩久久| jiyouzz国产精品久久| 欧美午夜一区二区| 久久久久国色av免费看影院| 国产精品成人免费在线| 日韩精品成人一区二区在线| 国产高清不卡二三区| 欧美三级电影一区| 国产亚洲欧美色| 亚洲与欧洲av电影| 国产成人亚洲综合a∨婷婷图片 | 1024亚洲合集| 人禽交欧美网站| 国产九色sp调教91| 欧美性猛片xxxx免费看久爱| 精品区一区二区| 亚洲一区二区三区激情| 国模大尺度一区二区三区| 一本久久a久久精品亚洲| 日韩美女在线视频 | 69av一区二区三区| 国产精品久久久久久久久快鸭| 天天综合色天天| 91香蕉视频在线| xf在线a精品一区二区视频网站| 亚洲国产中文字幕在线视频综合| 国产成人亚洲综合色影视| 7777精品伊人久久久大香线蕉超级流畅 | 国产精品久久久久久久久快鸭| 久久综合综合久久综合| 日本电影欧美片| 欧美国产日韩精品免费观看| 日韩高清不卡一区二区| 色综合中文字幕| 国产嫩草影院久久久久| 美腿丝袜一区二区三区| 欧美午夜电影一区| 国产精品网站在线观看| 青青草国产成人av片免费| 91国产免费观看| 亚洲欧美在线视频观看| 国产高清在线精品| 91精品国产综合久久福利软件 | 亚洲视频每日更新| 成人一区二区三区中文字幕| 日韩免费电影网站| 日本美女一区二区三区视频| 在线亚洲人成电影网站色www| 国产精品美女久久久久久2018 | 色诱视频网站一区| 国产精品成人免费| 国产高清精品久久久久| 久久久不卡网国产精品二区| 免费看精品久久片| 91精品国产福利在线观看| 亚洲一区二区三区四区在线| 91视频免费观看| 亚洲人成电影网站色mp4| 成人黄色免费短视频| 国产欧美一区二区精品性色| 国模套图日韩精品一区二区| 欧美一区二区啪啪| 人人超碰91尤物精品国产| 欧美久久久久免费| 天堂蜜桃一区二区三区| 在线91免费看| 玖玖九九国产精品| 337p粉嫩大胆噜噜噜噜噜91av| 精品系列免费在线观看| 2024国产精品视频| 国产成人精品一区二 | 久久99热99| 国产调教视频一区| 99久久精品国产导航| 一区二区三区日本| 欧美人动与zoxxxx乱| 青娱乐精品视频在线| 精品国产网站在线观看| 国产精品乡下勾搭老头1| 国产色91在线| 99视频在线观看一区三区| 中文字幕一区二区在线观看 | 国产福利一区二区三区视频在线| 国产精品的网站| 欧洲国内综合视频| 精品一区二区三区香蕉蜜桃 | 亚洲人成网站在线| 欧美日本一区二区三区| 蜜臀av国产精品久久久久| 久久综合九色综合97_久久久 | 北条麻妃一区二区三区| 一区二区欧美视频| 欧美一级理论片| 成人激情校园春色|