📄 messages.c
字号:
/*
Example of using different MessageControlBlocks as
specific messages. In this case "Switch Up" and "Switch Down"
Pay attention to the AvrXStack defined in the makefile on the
linker/loader command line. In general this should match the
stack passed to main() (end of ram).
The task definitions in this example have 20 extra bytes for
the task stack. Typically only one or two extra words of stack
are needed for AvrX calls. All other is for user code.
*/
#define ENABLE_BIT_DEFINITIONS
#include <avrx-io.h>
#include <avrx-signal.h>
#include "AvrX.h"
#include "hardware.h"
void InitSerialIO(unsigned char); // From Avrx.a (debug monitor)
AVRX_IAR_TASK(Monitor, 0, 20, 0);
AVRX_GCC_TASK(Monitor, 20, 0);
TimerControlBlock MyTimer; // Declare the control blocks needed for timers
MessageControlBlock SwitchUp, // Simple messages (no internal data)
SwitchDown;
MessageQueue MyQueue; // The message queue
/*
Timer 0 Overflow Interrupt Handler
Prototypical Interrupt handler:
. Switch to kernel context
. handle interrupt
. switch back to interrupted context.
*/
AVRX_SIGINT(SIG_OVERFLOW0)
{
IntProlog(); // Switch to kernel stack/context
outp(TCNT0_INIT, TCNT0); // Reset timer overflow count
AvrXTimerHandler(); // Call Time queue manager
Epilog(); // Return to tasks
}
/*
Task 1 Waits for a message, parses it and takes action.
*/
AVRX_IAR_TASKDEF(task1, 0, 10, 3)
AVRX_GCC_TASKDEF(task1, 10, 3)
{
MessageControlBlock *p;
while (1)
{
p = AvrXWaitMessage(&MyQueue);
if (p == &SwitchUp)
{
outp(0xFF, LED);
AvrXAckMessage(p);
}
else if (p == &SwitchDown)
{
outp(0x00, LED);
AvrXAckMessage(p);
}
else
AvrXHalt();
}
}
/*
Task 2 Checks switches every 10ms and sends a message SWITCH:0 changes
state
*/
AVRX_IAR_TASKDEF(task2, 0, 10, 3)
AVRX_GCC_TASKDEF(task2, 10, 3)
{
unsigned char previous, current;
previous = SWITCH; // Keep compiler happy
while (1)
{
AvrXDelay(&MyTimer, 10); // 10ms delay
if (previous != (current = (SWITCH&0x01)))
{
if (current == 0x01)
{
AvrXSendMessage(&MyQueue, &SwitchUp);
AvrXWaitMessageAck(&SwitchUp);
}
else
{
AvrXSendMessage(&MyQueue, &SwitchDown);
AvrXWaitMessageAck(&SwitchDown);
}
previous = current;
}
}
}
void main(void) // Main runs under the AvrX Stack
{
AvrXSetKernelStack(0);
outp((1<<SE), MCUCR); // Enable "Sleep" instruction
outp(TCNT0_INIT, TCNT0);
outp(TMC8_CK256, TCCR0); // Set up Timer0 for CLK/256 rate
outp((1<<TOIE0), TIMSK); // Enable Timer0 overflow interrupt
outp(0xFF, LEDDDR); // Make LED output and
outp(0xFF, LED); // drive high (LEDs off)
AvrXRunTask(TCB(task1));
AvrXRunTask(TCB(task2));
AvrXRunTask(TCB(Monitor));
InitSerialIO(UBRR_INIT); // Initialize USART baud rate generator
/* Needed for EEPROM access in monitor */
AvrXSetSemaphore(&EEPromMutex);
Epilog(); // Switch from AvrX Stack to first task
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -