hệ thống nhúng nó dành cho những công việc phức tạp lúc đó viết trên hệ điều hành của nó sẽ đơn giản hơn là mình lập trình thông thường. mình lấy ví dụ đơn giản như khi lập trình giao diện đồ họa trên C sẽ khó khăn hơn là lập trình giao diện đồ hoạ trên C# vì nó hỗ trợ nhiều hơn lập trình nhúng cũng như vậy
LẬP TRÌNH HỆ THỐNG NHÚNG BÙI QUỐC BẢO Concurrency (Tác vụ chạy đồng thời) Một hệ thống có hay nhiều tác vụ chạy ñộc lập VD: Một hệ thống dùng 8051 ñể: Bật/Tắt LED gắn vào P1.0 sau chu kỳ 500 ms Cho LED vàng-xanh-ñỏ sáng-tắt sau chu kỳ 500 ms Chia tác vụ thành máy trạng thái SM ñồng với chu kỳ 500 ms BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM LED SHOW Blink LED Period: 500 ms LEDON Rotate LED LEDOFF Period: 500 ms GREEN_ON YELLOW_ON RED_ON BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM enum BLState_t {OFF_STATE,ON_STATE} BLState; enum RTState_t {YELLOW_STATE, GREEN_STATE, RED_STATE} RTState; unsigned void char timerFlag = 0; TimerISR() { timerFlag = 1; } void … } void … } BL_Update() { RT_Update() { BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM void main(void) { outputInit(); timerInit(); BLStateInit(); STStateInit(); while (1) { while (!timerFlag); BL_Update(); RT_Update(); timerFlag = 0; } } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM Shared variable (biến dùng chung) Hoạt ñộng hệ thống chia thành nhiều tác vụ ñộc lập chúng có liên quan tới VD: Một hệ thống phát chuyển ñộng sử dụng sensor kết nối vào chân P1.0 Một chuyển ñộng ñược phát sensor lần lâý mẫu liên tiếp cách 200ms LED1 (nơí vào P1.1) ñược nhấp nháy sau với chu kỳ 200ms thời gian phát chuyển động LED2 (nơí vào P1.2) ñược bật phát chuyển ñộng tắt 10s sau chuyển động khơng cịn bị phát BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM Shared variable (biến dùng chung) !P1.0 !P1.0 P1.0 P1.0 S0 P1.0 S1 mnt = mnt = !P1.0 !mnt mnt !mnt && (cnt < 50) mnt mnt T0 S2 !mnt T1 T2 cnt = cnt++ !mnt && !(cnt < 50) BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM Shared variable (biến dùng chung) Chú ý: Chỉ có tác vụ ghi vào biến chung Nhiều tác vụ đọc biến chung VD Vẽ máy trạng thái cho hệ thống làm việc sau: Bật lị đốt cách set P1.0 nhiệt ñộ ño ñược (ñọc vào từ P2) nhỏ 100 Trong bật lò, chớp nháy LED nối vào P1.1 với chu kỳ 500ms ñể báo cho người dùng biết lị bật BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM Máy trạng thái có chu kỳ khác Các tác vụ với chu kỳ khác chạy cách sử dụng biến ñể ñếm số lần cờ timerFlag ñược bật (Timer tick) thực thi biến đạt đến giá trị mong muốn VD: Viết chương trình để 8051 chớp LED gắn vào P1.0 với chu kỳ 600 ms, cho LED xanh, vàng, ñỏ sáng sau khoảng thời gian 1s BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM enum enum static void { blState_t {LEDON, LEDOFF} BLState; blState_t {GREEN, YELLOW,RED} RTState; unsigned char timerFlag = 0; timerISR(void) timerFlag = 1; } void { … } void { … } BLUpdate RTUpdate BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 10 void main(void) { unsigned char BLTickCount = 0; unsigned char RTTickCount = 0; unsigned char BLTickPeriod = 3; unsigned char RTTickCount = 5; timerPeriodSet(200); BLInit(); RTInit(); runTimer(); while (1) { While (!timerFlag); BLTickCount++; RTTickCount++; If (BLTickCount == BLTickPeriod ) { BLUpdate(); BLTickCount = 0; } If (RTTickCount == RTTickCount ) { RTUpdate(); RTTickCount = 0; } } } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 11 Task Scheduler Trong chương trình có nhiều tác vụ chạy song song, đoạn chương trình định xem tác vụ ñược chạy gọi scheduler Một scheduler gồm: Hàm khởi tạo Hàm cập nhật thông số tác vụ, thực thi ngắt timer Một hàm thực thi tác vụ ñến thời ñiểm ñược chạy (dispatcher) Một hàm thêm tác vụ vào scheduler BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 12 Task Structure Mỗi tác vụ (task) có thơng số sau: (ví dụ tác vụ chớp led) Tên tác vụ (BLUpdate) Hằng số chứa thời gian lần thực thi (BLTickPeriod ) Biến ñếm số lần timer tick Một cờ báo tác vụ ñuợc cho phép chạy typedef data struct { void (code * ptask) unsigned char unsigned char unsigned char } taskStructType; (void); period ; count ; runMe; BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 13 Simple scheduler void main (void) { schedulerInit(); //khởi tạo scheduler /*Thêm tác vụ BLLED vào scheduler, tác vụ ñảo LED sau 1000 lần timer tick*/ schedulerAddTask(BLLed, 1000, 0); schedulerStart(); while (1) { schedulerDispatch(); } } void schedulerUpdate(void) interrupt using { //update tasks } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 14 Scheduler.h #ifndef SCHEDULER_H #define SCHEDULER_H #include #ifndef SCHEDULER_GLOBAL #define SCHEDULER_GLOBAL #else #define SCHEDULER_GLOBAL #endif #define SUCCEES (0) #define ERROR_TOO_MANY_TASK #define SCHEDULER_MAX_TASK extern (1) (3) BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 15 Scheduler.h typedef data struct { void (code * ptask) (void); unsigned char period ; unsigned char count ; unsigned char runMe; } taskStructType; void schedulerGotoSleep(void); void schedulerInit(void); void schedulerStart(void); unsigned char schedulerAddTask(void (code * pfunction)() , const unsigned char period, const unsigned char count ); void schedulerDispatch(void); #endif BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 16 Scheduler.c #define SCHEDULER_GLOBAL #include "scheduler.h" unsigned char errorCode; BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 17 Khởi tạo scheduler void schedulerInit() { unsigned char i; for (i=0;i> 8); TL0 = ((65536 - 50000) &0xFF); ET0 = 1; TR0 = 1; } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 18 Cập nhật trạng thái tác vụ void schedulerUpdate(void) interrupt using { unsigned char i; TR0 = 0; TF0 = 0; TH0 = ((65536 - 50000) >> 8); TL0 = ((65536 - 50000) &0xFF); TR0 = 1; for (i=0; i< SCHEDULER_MAX_TASK; i++) if (schedulerTask[i].ptask) { if ( schedulerTask[i].count == 0) { schedulerTask[i].runMe += 1; schedulerTask[i].count = schedulerTask[i].period; } } } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 19 Thêm tác vụ vào scheduler unsigned char schedulerAddTask(void (code * pfunction)() , const unsigned char period, const unsigned char count ) { unsigned char i; while ((schedulerTask[i].ptask != 0) && (i < SCHEDULER_MAX_TASK)) i++; if (i == SCHEDULER_MAX_TASK) { errorCode = ERROR_TOO_MANY_TASK; return SCHEDULER_MAX_TASK; } schedulerTask[i].ptask = pfunction; schedulerTask[i].period = period; schedulerTask[i].count = count + 1; schedulerTask[i].runMe = 0; return i; } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 20 10 Dispatcher void schedulerDispatch() { unsigned char i; for (i=0;i 0) { (*schedulerTask[i].ptask)(); schedulerTask[i].runMe -= 1; } } schedulerGotoSleep(); } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 21 void schedulerStart() { EA = 1; } void schedulerGotoSleep() { PCON |= 0x01; } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 22 11 main.c #include "scheduler.h" void BlinkLED() { P1 ^= 0x01; } void main(void) { schedulerInit(); schedulerAddTask(BlinkLED,20,0); schedulerStart(); while (1) { schedulerDispatch(); } } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 23 Triggered task ðơi khi, tác vụ cho phép tác động từ bên ngồi VD: ðèn giao thơng ñược ñiều khiển tay dùng nút bấm Tác vụ thiết kế cách lấy mẫu tín hiệu vào gọi ðể tăng tốc độ đáp ứng hệ thống, tác vụ ñược cho phép chạy cách dùng ngắt (trong trường hợp ngắt ngoài) BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 24 12 Triggered task void extISR0(void) interrupt using { schedulerTask[0].runMe = 1; schedulerTask[0].count = schedulerTask[0].period; } BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 25 Non-preemptive kernel Những hệ ñiều hành giống gọi nonpreemptive kernel Tác vụ phải tự trả quyền ñiều khiển CPU cho hệ ñiều hành Các “event” bất ñồng ñược ñiều khiển ISR Một ISR làm tác vụ có độ ưu tiên cao sẵn sàng chạy tác vụ hành chấm dứt, tác vụ ñược chạy BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 26 13 Non-preemptive kernel BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 27 Question Sửa scheduler ñể hỗ trợ mức ñộ ưu tiên cho tác vụ? BM Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 28 14 ... Bách Khoa TP.HCM Shared variable (biến dùng chung) Hoạt ñộng hệ thống chia thành nhiều tác vụ độc lập chúng có liên quan tới VD: Một hệ thống phát chuyển ñộng sử dụng sensor kết nối vào chân P1.0... chung) Chú ý: Chỉ có tác vụ ghi vào biến chung Nhiều tác vụ đọc biến chung VD Vẽ máy trạng thái cho hệ thống làm việc sau: Bật lị đốt cách set P1.0 nhiệt ñộ ño ñược (ñọc vào từ P2) nhỏ 100 Trong bật... Kỹ Thuật ðiện Tử - ðH Bách Khoa TP.HCM 11 Task Scheduler Trong chương trình có nhiều tác vụ chạy song song, đoạn chương trình định xem tác vụ ñược chạy gọi scheduler Một scheduler gồm: Hàm khởi