大家有没有兴趣一起写一个for AVR的RTOS
AVR的RAM比较大,用RTOS应该方便很多。我最近写了个简单的抢占式任务调度和消息传送内核,效果一般,不能动态添加进程。这方面我比较菜,各位高手出来联合一下吧,做个我们中国人的开源RTOS for AVR。 先贴我的源代码,写得很丑大家不要笑我// 镍镉电池组和镍氢电池组充电电路
// 使用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;
} 太好了
gcc写的,,
"ChargerAtmega8.h"在哪??LCD相关的呢? 顶一下。
关于RTOS我参考了,
http://www.freertos.org/implementation/index.html
可还没有想清楚,好像很繁琐,看不出多少优越性。
还有什么资料可以参考,请各位大侠多指教。 顶顶顶顶! OS的优越性还是很明显的,有OS以后程序的结构清晰了,各个任务也都能均匀的运行,同时也减小了开发的难度 有个叫r&s的rtos,国人做的,感觉还不错,大家不妨试试看 一个比较完善的RTOS可不是那么简单,否则适用意义还不如大家使用的前后台方式。曾经也是雄心勃勃在6502内核上作一个适用的RTOS,可是时间无法满足,还得上班啊,也许太务实了也是一种羁绊。 我觉得还是用别人已经测试过的RTOS,不用重复的开发 顶!!! 个人任务非强占式比较好用.很多强占式os应用中容易出的问题,可以避免掉. 抢占式系统中的线程同步很绕人。 个人觉得在8位单片机系统中用RTOS并不十分必要,尤其是用于电子色彩较浓的领域,而单片机之所以叫做MICRO CONTROL UNIT,就是因为它更多的适用于控制,软件方面重点在于硬件驱动的编写,而RTOS主要是为了管理多任务,属于应用系统级,事实上,在编写驱动的时候充分考虑可读性,可维护性与可移植性,其效果不亚于RTOS。
现在由于嵌入式系统的疯行,电子与计算机的界限已经模糊了,但是单片机系统的应用仍然偏向与电子这一块,而RTOS则带有很浓重的计算机色彩。
现代电子工程师=电子+计算机+机械+材料学+具体应用领域的专业知识 支持catayelo。
单片机系统的管理对象千差万别,RTOS能包容进去吗? RTOS 为应用提供了最基本的系统服务。在RTOS的基础上做应用,有许多基本功能的实现可以调用系统服务来实现。简化了开发过程,提高了系统的可靠性,缩短了开发周期。当然,代价是需要占用一定的系统资源。用不用RTOS要根据应用的具体情况,权衡利弊来决定。 RTOS如何确定各个任务stack的大小,请教那位DX能具体说说? 我觉得还是 小松工程 说的对!
没有必要,现在已经有很多很成熟的并且是全开放的源代码,为何不用??! 开源了,阿莫快给裤子吧!呵呵./emotion/em048.gif
./emotion/em059.gif 这里我写了一个,大家测试一下。
hoodng.cublog.cn 回复【12楼】catayelo
-----------------------------------------------------------------------
回复【17楼】ningmeng7294
开源了,阿莫快给裤子吧!呵呵./emotion/em048.gif
./emotion/em059.gif
-----------------------------------------------------------------------
说得确实很好,
不过LZ若是做为研究学习,也无不可
现代电子工程师=电子+计算机+机械+材料学+具体应用领域的专业知识,这个要求也太太高了吧 os优势在单片机里边挺明显的,但也非场合,有些场合不适用,而有些场合用os就是很快解决问题
我写的os很简单,不妨也测试测试,os调理很清楚,,见笑了
页:
[1]