/*****************************************************************************/
/* SCOOP LIBRARY / AUTHOR FABRICE OUDERT / GNU GPL V3 */
/* https://code.google.com/p/arduino-scoop-cooperative-scheduler-arm-avr/ */
/* VERSION 1.2 NEW YEAR PACK 10/1/2013 */
/* ENJOY AND USE AT YOUR OWN RISK :) */
/* SHOULD READ USER GUIDE FIRST (@\_/@) */
/*****************************************************************************/
#include "SCoop.h"
#define SCINM SCoopInstanceNickName
/********* GLOBAL VARIABLE *******/
SCoopEvent* SCoopFirstItem = NULL; // has to be initialized here. hold a pointer on the whole list of task/event/timer...
SCoopEvent* SCoopFirstTaskItem = NULL; // has to be initialized here. points to the first of all tasks registered in the list
uint8_t SCoopNumberTask = 0; // hold the number of task registered. used to calculate quantum in start(xxx)
SCoop SCoopInstanceNickName; // then we can use the library in the main sketch directly
#define SCINM SCoopInstanceNickName // just a local nickname...
#if SCoopANDROIDMODE >= 1
SCoop& ArduinoSchedulerNickName = SCINM; // this will create another identifier for the same object instance
#endif
/********* ASSEMBLY / LETS GET STARTED WITH THE COMPLEX THINGS **********/
// original idea for switching stack pointer taken out from ChibiOS.
// Credit to the author. now slightly modified.
// http://forum.pjrc.com/threads/540-ChibiOS-RTand-FreeRTOS-for-Teensy-3-0
//
// original idea for micros() optimization taken from CORE_TEENSY
// credit to Paul http://www.pjrc.com/teensy/
//************************************************************************/
#if defined(SCoop_ARM) && (SCoop_ARM == 1)
static void SCoopSwitch(uint8_t **newSP, uint8_t **oldSP) __attribute__((naked,noinline)) ;
static void SCoopSwitch(uint8_t **newSP, uint8_t **oldSP)
{ asm volatile ("push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}" : : : "memory");
asm volatile ("str sp, [%[oldsp], #0] \n\t"
"ldr sp, [%[newsp], #0]" : : [newsp] "r" (newSP), [oldsp] "r" (oldSP));
asm volatile ("pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, pc}" : : : "memory");
};
static inline uint32_t SCoopGetSP() __attribute__ ((always_inline)) ;
uint32_t SCoopGetSP() { register uint32_t val; asm ("mov %[temp],sp" : [temp] "=r" (val)); return val; }
#define ARM_ATOMIC ASM_ATOMIC
#define AVR_ATOMIC
#define SCoopMicros() ((micros_t)micros()) // overloading the standard micros()
#endif
#if defined(SCoop_AVR) && (SCoop_AVR == 1)
static void SCoopSwitch(void *newSP, void *oldSP) __attribute__((naked,noinline));
static void SCoopSwitch(void *newSP, void *oldSP)
{ asm volatile ("push r2 \n\t push r3 \n\t push r4 \n\t push r5 \n\t push r6 \n\t push r7 \n\t push r8 \n\t push r9 \n\t push r10 \n\t"
"push r11 \n\t push r12 \n\t push r13 \n\t push r14 \n\t push r15 \n\t push r16 \n\t push r17 \n\t push r28 \n\t push r29");
asm volatile ("movw r28, %[oldsp]" : : [oldsp] "r" (oldSP));
asm volatile ("in r2, 0x3d"); // SPL
asm volatile ("in r3, 0x3e"); // SPH
asm volatile ("std Y+0, r2"); // store the current SP into the pointer oldSP
asm volatile ("std Y+1, r3");
asm volatile ("movw r28, %[newsp]" : : [newsp] "r" (newSP));
asm volatile ("ldd r2, Y+0"); // restore the SP from the pointer newSP
asm volatile ("ldd r3, Y+1");
asm volatile ("in r4, 0x3f"); // save SREG
asm volatile ("cli "); // just to be safe on playing with stack ptr :) (useless with xmega)
asm volatile ("out 0x3e, r3"); // SPH
asm volatile ("out 0x3d, r2"); // SPL
asm volatile ("out 0x3f, r4"); // restore SREG asap (same approach as in setjmp.S credit to Marek Michalkiewicz)
asm volatile ("pop r29 \n\t pop r28 \n\t pop r17 \n\t pop r16 \n\t pop r15 \n\t pop r14 \n\t pop r13 \n\t pop r12 \n\t pop r11 \n\t"
"pop r10 \n\t pop r9 \n\t pop r8 \n\t pop r7 \n\t pop r6 \n\t pop r5 \n\t pop r4 \n\t pop r3 \n\t pop r2");
asm volatile ("ret"); };
#define SCoopGetSP() (uint16_t)SP // direct read access to SP register is possible
#define AVR_ATOMIC for ( uint8_t sreg_save __attribute__((__cleanup__(__iRestore))) = SREG, __ToDo = __iCliRetVal() ; __ToDo ; __ToDo = 0 )
static inline void __iRestore(const uint8_t *__s) { SREG = *__s; asm volatile ("" ::: "memory"); }
static inline uint8_t __iCliRetVal(void) { noInterrupts(); return 1; }
#define ARM_ATOMIC
/******** NEW MICROS METHOD BASED ON CORE_TEENSY / LIMITED TO 16 BITS **********/
/* Copyright (c) 2008-2010 PJRC.COM, LLC
* for the Teensy and Teensy++
* http://www.pjrc.com/teensy/
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#if F_CPU == 16000000L
#define TIMER0_MICROS_INC 4
#elif F_CPU == 8000000L
#define TIMER0_MICROS_INC 8
#elif F_CPU == 4000000L
#define TIMER0_MICROS_INC 16
#elif F_CPU == 2000000L
#define TIMER0_MICROS_INC 32
#elif F_CPU == 1000000L
#define TIMER0_MICROS_INC 64
#else
#define SCoopMicros() ((micros_t)micros()) // using the standard micros()
#warning "CPU Frequence not supported by the new micros() function"
#endif
#if defined(CORE_TEENSY)
extern volatile unsigned long timer0_micros_count; // this variable is incremented by timer 0 overflow
static inline micros_t SCoopMicros16(void) __attribute__((always_inline));
static inline micros_t SCoopMicros16(void) // same as standrad PJRC micros, but in 16 bits and with inlining
{ register micros_t out;
asm volatile(
"in __tmp_reg__, __SREG__" "\n\t"
"cli" "\n\t"
"in %A0, %2" "\n\t"
"in __zero_reg__, %3" "\n\t"
"lds %B0, timer0_micros_count" "\n\t"
"out __SREG__, __tmp_reg__" "\n\t"
"sbrs __zero_reg__, %4" "\n\t"
"rjmp L_%=_skip" "\n\t"
"cpi %A0, 255" "\n\t"
"breq L_%=_skip" "\n\t"
"subi %B0, 256 - %1" "\n\t"
"L_%=_skip:" "\n\t"
"clr __zero_reg__" "\n\t"
"clr __tmp_reg__" "\n\t"
#if F_CPU == 16000000L || F_CPU == 8000000L || F_CPU == 4000000L
"lsl %A0" "\n\t"
"rol __tmp_reg__" "\n\t"
"lsl %A0" "\n\t"
"rol __tmp_reg__" "\n\t"
#if F_CPU == 8000000L || F_CPU == 4000000L
"lsl %A0" "\n\t"
"rol __tmp_reg__" "\n\t"
#endif
#if F_CPU == 4000000L
"lsl %A0" "\n\t"
"rol __tmp_reg__" "\n\t"
#endif
"or %B0, __tmp_reg__" "\n\t"
#endif
#if F_CPU == 1000000L || F_CPU == 2000000L
"lsr %A0" "\n\t"
"ror __tmp_reg__" "\n\t"
"lsr %A0" "\n\t"
"ror __tmp_reg__" "\n\t"
#if F_CPU == 2000000L
"lsr %A0" "\n\t"
"ror __tmp_reg__" "\n\t"
#endif
"or %B0, %A0" "\n\t"
"mov %A0, __tmp_reg__" "\n\t"
#endif
: "=r" (out)
: "M" (TIMER0_MICROS_INC),
"I" (_SFR_
没有合适的资源?快使用搜索试试~ 我知道了~
项目源码基于树莓派和Arduino的智能温室
共4个文件
cpp:2个
py:1个
h:1个
需积分: 5 0 下载量 30 浏览量
2024-02-19
14:17:32
上传
评论
收藏 24KB ZIP 举报
温馨提示
【项目源码】基于树莓派和Arduino的智能温室
资源推荐
资源详情
资源评论
收起资源包目录
项目源码.zip (4个子文件)
项目源码
SCoop.cpp 38KB
SCoop.h 34KB
main.cpp 2KB
Communication.py 344B
共 4 条
- 1
资源评论
qq_38978479
- 粉丝: 27
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功