Tomcat 发表于 2005-4-20 00:32:29

大家有没有兴趣一起写一个for AVR的RTOS

AVR的RAM比较大,用RTOS应该方便很多。我最近写了个简单的抢占式任务调度和消息传送内核,效果一般,不能动态添加进程。这方面我比较菜,各位高手出来联合一下吧,做个我们中国人的开源RTOS for AVR。

Tomcat 发表于 2005-4-20 00:35:25

先贴我的源代码,写得很丑大家不要笑我



// 镍镉电池组和镍氢电池组充电电路

// 使用ATMega8单片机

// 创建于2004/12/15

// 最后一次修改 2005/3/22

// 版权没有



#include <avr/io.h>

#include <avr/wdt.h>

#include <avr/sleep.h>

#include <avr/signal.h>

#include <avr/interrupt.h>

#include <avr/pgmspace.h>

#include "ChargerAtmega8.h"



// UART value defInition

#define        UART_TX_BUFFER_SIZE        16        /* 1,2,4,8,16,32,64,128        or 256 bytes */

#define        UART_TX_BUFFER_MASK        (UART_TX_BUFFER_SIZE - 1)

#define VOL_BUFFER_LEN        6

#define UART_RX_BUFFER_SIZE        8

#define UART_RX_BUFFER_MASK        (UART_RX_BUFFER_SIZE - 1)



#if (UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK)

#error RX buffer size is not a power of        2

#endif



// UART Data

volatile unsigned char UART_TxBuf;

volatile unsigned char UART_RxBuf;

volatile unsigned char UART_TxHead;

volatile unsigned char UART_TxTail;

volatile unsigned char UART_RxTail;



// 系统状态

#define        READY                1

#define        CHARGING        2

#define        CHECKING        3

#define        FULL                4

volatile unsigned char gcState;



// 进程控制块

// PCB结构:0 程序指针,1 堆栈指针,2 进程状态字

// 状态字结构

//        Bit1 & Bit0        00-Ready 01-Running 10-Waiting

//Bit3 & Bit2 优先级 00-1 01-2 10-3 11-4

//        Bit11-Bit4        进程运行加权值

#define PROCESS_READY        0

#define PROCESS_RUNNING        1

#define PROCESS_WAITING        2

#define PROCESS_IDLE        3

struct ProcWord

{

        unsigned int Rank:8;                // 进程运行加权值

        unsigned int Priority:2;        // 优先级 00-1 01-2 10-3 11-4

        unsigned int State:2;                // 进程状态 00-Ready 01-Running 10-Waiting

};

struct ProcessControlBlock

{

        unsigned int StackPoint;

        unsigned char Message;        // 每个进程的消息池

        unsigned char WaitFor;        // 等待的事件/资源编号 0-8

        struct ProcWord ProcessWD;

};

// 进程标识

#define BAT_PROC        0

#define CUR_PROC        1

#define        KEY_PROC        2

#define        LCD_PROC        3

#define        STA_PROC        4

#define PCB_NUMBER        5

volatile struct ProcessControlBlock PCB;

volatile unsigned char gcRunningProcessID;

// 事件标识

// 消息通知每个进程,gcSignal中相应的位代表该进程是否有消息

volatile unsigned char gcSignal;

// 每种进程的消息定义

// 给Battary_Monitor进程的

#define        CHECK_BATTARY        1

#define        EXT_ADC_ENDED        2

#define        CURRENT_STOP        4

// 给Current_Monitor进程的

#define CHK_CUR_ENDED        1

#define CURRENT_ON                2

#define CURRENT_OFF                4

// 给Keyboard_Monitor进程的

#define CHK_KEY_ENDED        1

#define KEY_GET_READY        2

#define CHECK_KEY                4

// 给LCD_Monitor进程的

#define UPDATE_VOLTAGE        1

#define UPDATE_CURRENT        2

#define LCD_GET_READY        4

#define MOVE_CURSOR_LEFT        8

#define        MOVE_CURSOR_RIGHT        16

#define ENTER_ITEM                32

#define LCD_FLASH                64

// 给State_Monitor进程的

#define LCD_READY                1

#define START_CHARGE        2

#define        STOP_CHARGE                4

#define        BAT_AD_ENDED        8

#define        SOUND_FLASH                16



volatile unsigned int SYSTEM_STACK;

volatile unsigned int gnADC_CUR,gnADC_KEY;

volatile unsigned char gcMillisecond;

volatile unsigned char gcSecond,gcTenSecond,gcMinute;

volatile unsigned long glSumCurrent;

// 设定的充电电流值

volatile unsigned int gnCurrent;

// 设定的电池类型

volatile unsigned char gcTypeOfBattary;

// 电压队列

#define VOLT_ARRAY_LEN        18

volatile unsigned int gnVoltageArray;

volatile unsigned int gnVoltage;



volatile unsigned char gcI = 0, gcJ = 0;

volatile unsigned char gacMenu;        // 菜单选择位置



int main(void)

{

        // 响一下

        sbi(DDRC, 2);sbi(PORTC, 2);

        sbi(DDRB, 2);cbi(PORTB, 2);

       

        gcSignal = 0; gcADC_In_Use = false;

        gnVoltage = 0;

        gcMillisecond = 0; gcSecond = 0; gcTenSecond = 0; gcMinute = 0;

        UART_TxHead = 0; UART_TxTail = 0; UART_RxTail = 0;

       

        // 初始化每个进程的状态为READY 消息为空

        for(unsigned char i = 0; i < 5; i++)

        {

                PCB.ProcessWD.State = PROCESS_READY;

                PCB.Message = 0;

        }

        // 设定各进程优先级

        PCB.ProcessWD.Priority = 2;

        PCB.ProcessWD.Priority = 1;

        PCB.ProcessWD.Priority = 1;

        PCB.ProcessWD.Priority = 0;

        PCB.ProcessWD.Priority = 0;

        // 备份系统堆栈

        SYSTEM_STACK = SP;

       

        // 给各个进程分配独自堆栈空间 初始化堆栈

        SP = SYSTEM_STACK - 128;

        _SFR_MEM8(SP--) = (unsigned int)Battary_Monitor&0xFF;

        _SFR_MEM8(SP--) = (unsigned int)Battary_Monitor>>8;

        for(unsigned char i = 0; i <= 32; i++) asm volatile("push __zero_reg__"::);

        PCB.StackPoint = SP;

       

        SP = SYSTEM_STACK - 256;

        _SFR_MEM8(SP--) = (unsigned int)Current_Monitor&0xFF;

        _SFR_MEM8(SP--) = (unsigned int)Current_Monitor>>8;

        for(unsigned char i = 0; i <= 32; i++) asm volatile("push __zero_reg__"::);

        PCB.StackPoint = SP;

       

        SP = SYSTEM_STACK - 384;

        _SFR_MEM8(SP--) = (unsigned int)Keyboard_Monitor&0xFF;

        _SFR_MEM8(SP--) = (unsigned int)Keyboard_Monitor>>8;

        for(unsigned char i = 0; i <= 32; i++) asm volatile("push __zero_reg__"::);

        PCB.StackPoint = SP;



        SP = SYSTEM_STACK - 512;

        _SFR_MEM8(SP--) = (unsigned int)LCD_Monitor&0xFF;

        _SFR_MEM8(SP--) = (unsigned int)LCD_Monitor>>8;

        for(unsigned char i = 0; i <= 32; i++) asm volatile("push __zero_reg__"::);

        PCB.StackPoint = SP;



        SP = SYSTEM_STACK;

        PCB.StackPoint = SP;

       

        // 设波特率为9600

        Init_UART(51);

        // 初始化ADC

        Init_Internal_ADC();

        // 初始化TC2

        Init_TC2();

        // 设置看门狗

        wdt_enable(WDTO_60MS);

        // 允许睡眠模式

        set_sleep_mode(0);

        // TCCR0分频64

        TCCR0 = 0x03;

        // 开定时器0中断

        sbi(TIMSK,TOIE0);

        // 允许全局中断

        sei();

        TransmitByte('S');

       

        gcRunningProcessID = STA_PROC;

        State_Monitor();

}



void Scheduler(void)

{

        wdt_reset();

        for(unsigned char i = 0; i < PCB_NUMBER; i++)

        {

                if(bit_is_set(gcSignal, i) && PCB.Message&PCB.WaitFor

               && (PCB.ProcessWD.State == PROCESS_WAITING))

                {

                        cbi(gcSignal, i);

                        PCB.WaitFor = 0;

                        PCB.ProcessWD.State = PROCESS_READY;

                }

        }

       

        unsigned char cHighProcess = 0;

        unsigned int nPriority,nPriority1;

        if(PCB.ProcessWD.State == PROCESS_READY)

        {

                PCB.ProcessWD.Rank++;

                nPriority = PCB.ProcessWD.Priority*4 + PCB.ProcessWD.Rank;

        }

        else

        {

                nPriority = 0;

                cHighProcess = 1;

        }

        for(unsigned char i=1; i < PCB_NUMBER; i++)

        {

                if(PCB.ProcessWD.State == PROCESS_READY)

                {

                        PCB.ProcessWD.Rank++;

                        nPriority1 = PCB.ProcessWD.Priority*4 + PCB.ProcessWD.Rank;

                        if(nPriority < nPriority1)

                        {

                                cHighProcess = i;

                                nPriority = nPriority1;

                        }

                }

        }



        PCB.ProcessWD.State = PROCESS_RUNNING;

        PCB.ProcessWD.Rank = 0;

        gcRunningProcessID = cHighProcess;

}



void Idle(void)

{

        PCB.ProcessWD.State = PROCESS_READY;

        Wait();

}



void Wait_Message(unsigned char Message)

{

        PCB.ProcessWD.State = PROCESS_WAITING;

        PCB.WaitFor = Message;

        Wait();

}



void Wait(void)

{

        asm volatile("pop r17
\tpop r16"::);

        asm volatile("push __zero_reg__
\tpush __tmp_reg__"::);

        asm volatile("in __tmp_reg__,__SREG__"::);

        asm volatile("push __tmp_reg__
\tclr __zero_reg__"::);

        asm volatile("push r18
\tpush r19
\tpush r20"::);

        asm volatile("push r21
\tpush r22
\tpush r23"::);

        asm volatile("push r24
\tpush r25
\tpush r26"::);

        asm volatile("push r27
\tpush r30
\tpush r31"::);

        cbi(TIMSK,TOIE0);

        asm volatile("push r2
\tpush r3
\tpush r4"::);

        asm volatile("push r5
\tpush r6
\tpush r7"::);

        asm volatile("push r8
\tpush r9
\tpush r10"::);

        asm volatile("push r11
\tpush r12
\tpush r13"::);

        asm volatile("push r14
\tpush r15
\tpush r16"::);

        asm volatile("push r17
\tpush r28
\tpush r29"::);

        PCB.StackPoint = SP;

        Scheduler();

        SP = PCB.StackPoint;

        asm volatile("pop r29
\tpop r28
\tpop r17"::);

        asm volatile("pop r16
\tpop r15
\tpop r14"::);

        asm volatile("pop r13
\tpop r12
\tpop r11"::);

        asm volatile("pop r10
\tpop r9
\tpop r8"::);

        asm volatile("pop r7
\tpop r6
\tpop r5"::);

        asm volatile("pop r4
\tpop r3
\tpop r2"::);

        sbi(TIMSK,TOIE0);

        asm volatile("pop r31
\tpop r30
\tpop r27"::);

        asm volatile("pop r26
\tpop r25
\tpop r24"::);

        asm volatile("pop r23
\tpop r22
\tpop r21"::);

        asm volatile("pop r20
\tpop r19
\tpop r18"::);

        asm volatile("pop __tmp_reg__
\tout __SREG__,__tmp_reg__"::);

        asm volatile("pop __tmp_reg__
\tpop __zero_reg__"::);

        asm volatile("reti"::);

}



void Send_Message(unsigned char ProcessID, unsigned char Message)

{

        sbi(gcSignal, ProcessID);

        PCB.Message |= Message;

}



void Battary_Monitor(void)

{

        while(1)

        {

                UDR = 0x37;

                Wait_Message(CHECK_BATTARY);

                PCB.Message = 0;

                if(gcState == CHARGING)

                {

                        UDR = 'a';

                        Send_Message(CUR_PROC, CURRENT_OFF);

                        Wait_Message(CURRENT_STOP);

                }

                UDR = 'A';

                unsigned int nVoltageArray;

                for(unsigned char i = 0; i < 6; i++)

                {

                        Init_TC1(ICP);

                        Start_External_ADC();

                        Wait_Message(EXT_ADC_ENDED);

                        PCB.Message = 0;

                        Stop_External_ADC();

                        nVoltageArray = gnVoltage;

                }

                UDR = 0x30+gcState;

                if(gcState == CHECKING) Send_Message(CUR_PROC, CURRENT_ON);

                gnVoltage = Average(nVoltageArray, 6);

                Send_Message(LCD_PROC, UPDATE_VOLTAGE);

                Send_Message(STA_PROC, BAT_AD_ENDED);

        }

}



void Current_Monitor(void)

{

        unsigned int nSumCount = 0, nPWM_Duty = 0;

        unsigned long lSumCurrent = 0;

        glSumCurrent = 0;

        while(1)

        {

                if(gcState == CHARGING)

                {

                        if(PCB.Message&CURRENT_OFF)

                        {

                                gcState = CHECKING;

                                PCB.Message &= ~CURRENT_OFF;

                                Start_TC1(CLKSTOP);

                                cbi(PORTB,1);

                                cbi(DDRB,1);

                                Send_Message(BAT_PROC, CURRENT_STOP);

                        }

                        else

                        {

                                // 启动电流检查

                                while(!Run_Internal_ADC(CURRENT)) Idle();

                                // 等AD转换结束

                                Wait_Message(CHK_CUR_ENDED);

                                PCB.Message &= ~CHK_CUR_ENDED;

                                // 调整电流

                                if(gnADC_CUR < gnCurrent) nPWM_Duty++;

                                else if(gnADC_CUR > gnCurrent) nPWM_Duty--;

                                OCR1A = nPWM_Duty;

                                // 求测得的电流平均值并显示 每512次采样求一次

                                lSumCurrent += gnADC_CUR;

                                if(++nSumCount >= 512)

                                {

                                        nSumCount = 0;

                                        Send_Message(LCD_PROC, UPDATE_CURRENT);

                                        glSumCurrent = lSumCurrent;

                                        lSumCurrent = 0;

                                }

                        }

                }

                else if(gcState == CHECKING)

                {

                        if(PCB.Message&CURRENT_ON)

                        {

                                gcState = CHARGING;

                                PCB.Message &= ~CURRENT_ON;

                                Init_TC1(PWM);

                                OCR1A = nPWM_Duty;

                                Start_TC1(CLKIO);

                        }

                }

                else

                {

                        cbi(PORTB,1);

                        cbi(DDRB,1);

                        Idle();

                }

        }

}



void Keyboard_Monitor(void)

{

        unsigned char cKey_Count = 0;

        // 初始化菜单

        // 菜单

        gacMenu = 2;

        gacMenu = 29;

        gacMenu = 7;

        gacMenu = 1;

        gacMenu = 0;

        gacMenu = 0;

        gacMenu = 0;

        gacMenu = 0;

        Wait_Message(KEY_GET_READY);

        PCB.Message = 0;

        while(1)

        {

                Wait_Message(CHECK_KEY);

                PCB.Message = 0;

                // 启动键盘扫描

                while(!Run_Internal_ADC(KEY_BOARD)) Idle();

                // 等AD转换结束

                Wait_Message(CHK_KEY_ENDED);

                PCB.Message = 0;

                unsigned int nKey = gnADC_KEY;

                if(gnADC_KEY < 800)

                {

                        // 消抖晃

                        if(++cKey_Count == 10)

                        {

                                if(nKey < 100)

                                {

                                        if(gcJ == 0)

                                        {

                                                if(gcI > 0) gcI--;

                                                else gcI = 3;

                                        }

                                        else

                                        {

                                                if(gacMenu > 0) gacMenu--;

                                                else gacMenu = gacMenu;

                                        }

                                        if(gcState == READY) Send_Message(LCD_PROC, MOVE_CURSOR_LEFT);

                                        UDR = '-';

                                }

                                else if(nKey > 300 && nKey < 360)

                                {

                                        if(gcJ == 0) gcJ = 1;

                                        else gcJ = 0;

                                        if(gcI == 3)

                                        {

                                                if(gcState == READY)

                                                {

                                                        UDR = 's';

                                                        gnCurrent = (gacMenu + 1)*25;

                                                        gcTypeOfBattary = gacMenu;

                                                        Send_Message(STA_PROC, START_CHARGE);

                                                        Clear_Screen(LOW);

                                                }

                                                else if(gcState == CHARGING || gcState == CHECKING)

                                                {

                                                        UDR = 't';

                                                        Send_Message(STA_PROC, STOP_CHARGE);

                                                }

                                        }

                                        Send_Message(LCD_PROC, ENTER_ITEM);

                                        UDR = 'E';

                                }

                                else if(nKey > 616 && nKey < 716)

                                {

                                        if(gcJ == 0)

                                        {

                                                if(gcI < 3) gcI++;

                                                else gcI = 0;

                                        }

                                        else

                                        {

                                                if(gacMenu < gacMenu) gacMenu++;

                                                else gacMenu = 0;

                                        }

                                        if(gcState == READY) Send_Message(LCD_PROC, MOVE_CURSOR_RIGHT);

                                        UDR = '+';

                                }

                        }

                }

                else cKey_Count = 0;

        }

}



void LCD_Monitor(void)

{

        // 初始化液晶屏

        Init_Screen();

        Send_Message(STA_PROC, LCD_READY);        // 通知State_Monitor LCD初始化完成

        Wait_Message(LCD_GET_READY);                // 等待State_Monitor回应

        PCB.Message = 0;

        Clear_Screen(ALL);                                        // 清屏

        Display_Battary_Type(gacMenu, NORM);

        Display_Battary_Cap(gacMenu, NORM);

        Display_Battary_Voltage(gacMenu, NORM);

        Display_Start_Stop(1);

        Display_Arrow(gcI);

        while(1)

        {

                if(PCB.Message & UPDATE_VOLTAGE)

                {

                        PCB.Message &= ~UPDATE_VOLTAGE;

                        Voltage_To_Screen(gnVoltage);

                }

                if(PCB.Message & UPDATE_CURRENT)

                {

                        PCB.Message &= ~UPDATE_CURRENT;

                        Current_To_Screen((glSumCurrent>>9)*2);

                }

                if(PCB.Message & MOVE_CURSOR_LEFT)

                {

                        UDR = 'L';

                        PCB.Message &= ~MOVE_CURSOR_LEFT;

                        if(gcJ == 1)

                        {

                                if(gcI == 0) Display_Battary_Type(gacMenu, REVERSE);

                                else if(gcI == 1) Display_Battary_Cap(gacMenu, REVERSE);

                                else if(gcI == 2) Display_Battary_Voltage(gacMenu, REVERSE);

                        }

                        else Display_Arrow(gcI);

                }

                if(PCB.Message & MOVE_CURSOR_RIGHT)

                {

                        UDR = 'R';

                        PCB.Message &= ~MOVE_CURSOR_RIGHT;

                        if(gcJ == 1)

                        {

                                if(gcI == 0) Display_Battary_Type(gacMenu, REVERSE);

                                else if(gcI == 1) Display_Battary_Cap(gacMenu, REVERSE);

                                else if(gcI == 2) Display_Battary_Voltage(gacMenu, REVERSE);

                        }

                        else Display_Arrow(gcI);

                }

                if(PCB.Message & ENTER_ITEM)

                {

                        PCB.Message &= ~ENTER_ITEM;

                        if(gcJ == 1)

                        {

                                if(gcI == 0) Display_Battary_Type(gacMenu, REVERSE);

                                else if(gcI == 1) Display_Battary_Cap(gacMenu, REVERSE);

                                else if(gcI == 2) Display_Battary_Voltage(gacMenu, REVERSE);

                        }

                        else

                        {

                                if(gcI == 0) Display_Battary_Type(gacMenu, NORM);

                                else if(gcI == 1) Display_Battary_Cap(gacMenu, NORM);

                                else if(gcI == 2) Display_Battary_Voltage(gacMenu, NORM);

                        }

                }

                if(PCB.Message & LCD_FLASH)

                {

                        PCB.Message &= ~LCD_FLASH;

                }

        }

}



void State_Monitor(void)

{

        unsigned char cTime = 0;

        Wait_Message(LCD_READY);

        PCB.Message = 0;

        Beep(OFF);

        gcState = READY;

        Send_Message(LCD_PROC, LCD_GET_READY);        // 启动LCD进程

        Send_Message(KEY_PROC, KEY_GET_READY);        // 启动键盘监控进程

        while(1)

        {

                if(gcState == READY)

                {

                        Wait_Message(START_CHARGE);

                        // 是否收到开始充电的信号

                        if(PCB.Message & START_CHARGE)

                        {

                                PCB.Message &= ~START_CHARGE;

                                gcState = CHARGING;

                                Send_Message(BAT_PROC, CHECK_BATTARY);

                        }

                }

                if(gcState == CHARGING || gcState == CHECKING)

                {

                        Wait_Message(STOP_CHARGE|BAT_AD_ENDED);

                        // 是否收到停止充电的信号

                        if(PCB.Message & STOP_CHARGE)

                        {

                                PCB.Message &= ~STOP_CHARGE;

                                gcState = READY;        // 暂停充电 置充电器为READY状态

                        }

                        if(PCB.Message & BAT_AD_ENDED)

                        {

                                PCB.Message &= ~BAT_AD_ENDED;

                                // 判断电池是否充满

                                for(unsigned char i = VOLT_ARRAY_LEN-1; i > 0; i--)

                                gnVoltageArray = gnVoltageArray;        // 电压值队列顺序移位

                                gnVoltageArray = gnVoltage;

                                if(Battary_Full(gnVoltageArray, gcTypeOfBattary))

                                {

                                        gcState = FULL;

                                }

                        }

                }

                if(gcState == FULL)

                {

                        Wait_Message(SOUND_FLASH);

                        PCB.Message &= ~SOUND_FLASH;

                        Display_Full();

                        if(++cTime == 8)

                        {

                                Beep(ON);

                                cTime = 0;

                        }

                        else Beep(OFF);

                }

        }

}



INTERRUPT(SIG_OVERFLOW0)

{

        asm volatile("push r2
\tpush r3
\tpush r4"::);

        asm volatile("push r5
\tpush r6
\tpush r7"::);

        asm volatile("push r8
\tpush r9
\tpush r10"::);

        asm volatile("push r11
\tpush r12
\tpush r13"::);

        asm volatile("push r14
\tpush r15
\tpush r16"::);

        asm volatile("push r17
\tpush r28
\tpush r29"::);

        PCB.ProcessWD.State = PROCESS_READY;

        if(++gcMillisecond == 255)

        {

                UDR = 0x30+gcState;

                gcMillisecond = 0;

                if(gcState == READY) Send_Message(LCD_PROC, LCD_FLASH);

                else if(gcState == FULL) Send_Message(STA_PROC, SOUND_FLASH);

                if(++gcSecond >= 20)

                {

                        if(gcState == CHARGING)

                        {

                                if(gcTenSecond & 0x01) Send_Message(BAT_PROC, CHECK_BATTARY);

                        }

                        UDR = 'M';

                        gcSecond = 0;

                        if(++gcTenSecond >= 6)

                        {

                                gcTenSecond = 0;

                                gcMinute++;

                        }

                }

        }

        Send_Message(KEY_PROC, CHECK_KEY);

        PCB.StackPoint = SP;

        Scheduler();

        SP = PCB.StackPoint;

        asm volatile("pop r29
\tpop r28
\tpop r17"::);

        asm volatile("pop r16
\tpop r15
\tpop r14"::);

        asm volatile("pop r13
\tpop r12
\tpop r11"::);

        asm volatile("pop r10
\tpop r9
\tpop r8"::);

        asm volatile("pop r7
\tpop r6
\tpop r5"::);

        asm volatile("pop r4
\tpop r3
\tpop r2"::);

}



INTERRUPT(SIG_INPUT_CAPTURE1)

{

        unsigned int temp = 0;

        temp = ICR1L;

        temp |= ICR1H << 8;

        if(bit_is_set(TCCR1B,ICES1))

        {

                cbi(TCCR1B, ICES1);

                gnVoltage = temp;

        }

        else

        {

                gnVoltage = temp - gnVoltage;

                gnVoltage -= 0x2711;

                Send_Message(BAT_PROC, EXT_ADC_ENDED);

        }

}



INTERRUPT(SIG_ADC)

{

        unsigned int nADC = ADCL;

        nADC |= ADCH << 8;

        unsigned char temp = ADMUX;

        temp &= 0x0F;

        if(temp == CURRENT)

        {

                gnADC_CUR = nADC;

                Send_Message(CUR_PROC, CHK_CUR_ENDED);

        }

        else if(temp == KEY_BOARD)

        {

                gnADC_KEY = nADC;

                Send_Message(KEY_PROC, CHK_KEY_ENDED);

        }

        ADMUX &= 0xF0;

        gcADC_In_Use = false;

}



SIGNAL(SIG_UART_DATA)

{

        /* check if all data is transmitted */

        if(UART_TxHead != UART_TxTail )

        {

                /* calculate buffer index */

                UART_TxTail = (UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;

                UDR = UART_TxBuf; /* start transmition        */

        }

        else cbi(UCSRB,UDRIE);        // disable UDR interrupt

}



SIGNAL(SIG_UART_RECV)

{

        unsigned char cReceivedByte;

        cReceivedByte = UDR;

//        TransmitByte(cReceivedByte);        // 回显字符

        UART_RxBuf = cReceivedByte;

        UART_RxTail = (UART_RxTail + 1) & UART_TX_BUFFER_MASK;

}

harrylee 发表于 2005-4-20 00:48:01

太好了

gcc写的,,

"ChargerAtmega8.h"在哪??LCD相关的呢?

testcode 发表于 2005-4-20 07:25:27

顶一下。

关于RTOS我参考了,

http://www.freertos.org/implementation/index.html

可还没有想清楚,好像很繁琐,看不出多少优越性。

还有什么资料可以参考,请各位大侠多指教。

windows 发表于 2005-4-20 14:25:39

顶顶顶顶!

Tomcat 发表于 2005-4-20 19:52:01

OS的优越性还是很明显的,有OS以后程序的结构清晰了,各个任务也都能均匀的运行,同时也减小了开发的难度

ldqmoon 发表于 2005-4-21 09:02:05

有个叫r&s的rtos,国人做的,感觉还不错,大家不妨试试看

tiny26 发表于 2005-4-21 09:31:18

一个比较完善的RTOS可不是那么简单,否则适用意义还不如大家使用的前后台方式。曾经也是雄心勃勃在6502内核上作一个适用的RTOS,可是时间无法满足,还得上班啊,也许太务实了也是一种羁绊。

ilan2003 发表于 2005-4-21 09:41:32

我觉得还是用别人已经测试过的RTOS,不用重复的开发

lei_yong 发表于 2005-6-1 06:12:45

顶!!!

q123321 发表于 2005-6-1 16:18:50

个人任务非强占式比较好用.很多强占式os应用中容易出的问题,可以避免掉.

stdio 发表于 2005-6-2 00:16:21

抢占式系统中的线程同步很绕人。

catayelo 发表于 2005-8-22 16:08:52

个人觉得在8位单片机系统中用RTOS并不十分必要,尤其是用于电子色彩较浓的领域,而单片机之所以叫做MICRO CONTROL UNIT,就是因为它更多的适用于控制,软件方面重点在于硬件驱动的编写,而RTOS主要是为了管理多任务,属于应用系统级,事实上,在编写驱动的时候充分考虑可读性,可维护性与可移植性,其效果不亚于RTOS。



现在由于嵌入式系统的疯行,电子与计算机的界限已经模糊了,但是单片机系统的应用仍然偏向与电子这一块,而RTOS则带有很浓重的计算机色彩。



现代电子工程师=电子+计算机+机械+材料学+具体应用领域的专业知识

zzqq 发表于 2005-8-24 02:50:33

支持catayelo。

单片机系统的管理对象千差万别,RTOS能包容进去吗?

lei_yong 发表于 2005-8-24 13:38:09

RTOS 为应用提供了最基本的系统服务。在RTOS的基础上做应用,有许多基本功能的实现可以调用系统服务来实现。简化了开发过程,提高了系统的可靠性,缩短了开发周期。当然,代价是需要占用一定的系统资源。用不用RTOS要根据应用的具体情况,权衡利弊来决定。

testcode 发表于 2005-8-24 23:30:16

RTOS如何确定各个任务stack的大小,请教那位DX能具体说说?

xiaobao601 发表于 2006-9-27 21:42:17

我觉得还是 小松工程 说的对!

没有必要,现在已经有很多很成熟的并且是全开放的源代码,为何不用??!

ningmeng7294 发表于 2006-9-27 23:32:47

开源了,阿莫快给裤子吧!呵呵./emotion/em048.gif





                   ./emotion/em059.gif

hoodng 发表于 2006-12-29 13:22:52

这里我写了一个,大家测试一下。

hoodng.cublog.cn

sophy.lin 发表于 2010-8-29 10:10:14

回复【12楼】catayelo
-----------------------------------------------------------------------

回复【17楼】ningmeng7294
开源了,阿莫快给裤子吧!呵呵./emotion/em048.gif
                   ./emotion/em059.gif
-----------------------------------------------------------------------
说得确实很好,
不过LZ若是做为研究学习,也无不可

现代电子工程师=电子+计算机+机械+材料学+具体应用领域的专业知识,这个要求也太太高了吧

avr-arm 发表于 2010-8-29 22:16:10

os优势在单片机里边挺明显的,但也非场合,有些场合不适用,而有些场合用os就是很快解决问题
我写的os很简单,不妨也测试测试,os调理很清楚,,见笑了
页: [1]
查看完整版本: 大家有没有兴趣一起写一个for AVR的RTOS