2.1 RTOS
RAM gồm vùng nhớ hệ thống và phần còn lại là vùng nhớ heap dành cho các task,
mỗi task tương ứng với (stack, control block)
heap_4 giúp chống phân mảnh, tận dụng vùng nhớ khi 1 task hoàn thành (giải phóng
bộ nhớ).
mỗi task tương ứng với 1 hàm thực thi, tham số task,
bộ hàm của API của stm32 khác bộ hàm free RTOS, bộ hàm API CMSIS-v2 )có thể
dùng cho nhiều nhiều hệ điều hành thời thực khác. link api
2.2 tổ chức chương trình theo chế độ chạy liên tục
link video bài giảng của thầy về hàm printf, time slice, preemption
2.2.1 lý thuyết về chế độ chạy liên tục :
yêu cầu: các task có mức ưu tiên bằng nhau, hàm thực thi là vòng lặp vô hạn.
các task chỉ có 2 trang thái running-chạy và ready-'sẵn sàng để chạy' (task ở trong
hàng đợi-theo cơ chế FIFO,
ban đầu các task cùng ready, do cùng mức ưu tiên nên task nào được khởi tạo trc sẽ
thoát chế độ ready và running trước (tại 1 thời điểm chỉ có tối đa 1 task running).
task sẽ running trong thời gian là 1 time slice (1 ms), khi hết time slice thì task bị
ngắt, nó sẽ chuyển từ running → ready (xếp vào cuối hàng đợi).
tại mốc thời gian time slice sẽ có ngắt hệ thống của kernel (bộ lập lịch) lưu trạng thái
của task trước và nạp trạng thái của task tiếp theo, task ready ở đầu hàng đợi sẽ
được running.
cứ như vậy thay các task thay phiên nhau running trong time slice của mình rồi lại
ready.
2.2.2 hàm, thư viện sử dụng
// thư viện
#include "cmsis_os.h"
//vd tham số, thuộc tính của task
/* Definitions for NORMAL_TASK */
osThreadId_t NORMAL_TASKHandle;
const osThreadAttr_t NORMAL_TASK_attributes = {
.name = "NORMAL_TASK",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
//khởi tạo bộ lập lịch kernel
osKernelInitialize();
//vd khởi tạo các task (tên hàm, thuộc tính...)
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL,
&defaultTask_attributes);
// bộ lập lịch bắt dầu chạy
osKernelStart();
2.2.3 cấu hình CUBMX
phần RCC, clock, GPIO làm như bình thường.
nên chọn time base khác system tick link giải thích
chọn FREERTOS, middware: CMSISV2 (api v1 hay v2, PREEMPTION (chiếm quyền),
thời gian mỗi time_slice (TICK_RATE, minimal stack size (kích thước stack nhỏ nhất),
queue registry size (kích thước hàng đợi), kích cỡ bộ nhớ heap, heap_4, ....
//vd hàm thực thi của task
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN 5 */
uint16_t u1;
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(GPIOA, LED1_Pin);
for(u1=0; u1<10000; u1++){ }
//osDelay(1);
}
/* USER CODE END 5 */
}
tạo task (tên task, mức ưu tiên, kích thước, tên hàm...)
2.2.4 VD chương trình:
các task cùng mức ưu tiên, ko dùng osDelay trong vòng lặp vô hạn, thực hiện nháy
led.
khi đó task sẽ lần lượt vào các trạng thái: ready3→ready2→ready1→running-
>ready3...
các vấn để: thời gian chuyển task tạm coi là nhỏ. thời gian thực hiện task lớn hơn
time slice nên task bị ngắt khi tới time slice nhưng thời gian ready rồi trở lại running
trong khoảng thời gian đủ nhỏ . sử dụng 3 led khác nhau nên ko xung đột tài nguyên.
link ví dụ
2.3 tổ chức chương trình theo sự kiện (task có mức
ưu tiên).
link video bài giảng của thầy về hàm printf, time slice, preemption
2.3.1 lý thuyết
ban đầu khi các task ở trạng thái ready (trong hàng đợi), do các task có mức ưu tiên
khác nhau nên task nào có mức ưu tiên cao nhất thì sẽ running trước. khi đến time
slice thì task đó trở lại trang thái ready. Nhưng khi so sánh mức ưu tiên của các task
đang ready thì nó vẫn là task có mức ưu tiên cao nhất nên tiếp tục running. Cứ như
vậy task có mức ưu tiên cao nhất chiếm hết thời gian hệ thống.
muốn tránh task có mức ưu tiên cao nhất chiếm hết thời gian hệ thống, thì ta có thể
dùng hàm osDelay. khi đó task có mức ưu tiên cao sẽ rơi vào trang thái block, task
có mức ưu tiên thấp hơn khác có cơ hội được thực hiện. sau 1 khoảng thời gian
osDelay thì task bị block sẽ chuyền về ready và có thể running.
một cách delay khác đó là delay theo mốc thời gian:
1 task có thể cầu hình lại mức ưu tiên của task khác
__IO uint32_t tick2 = osKernelGetTichCount();
tick2+=500;
//do something
osDelayUntil(tich2);
1 task tạo ra 1 task khác, rồi task thậm chí xoá chính nó,
một task có thể suspended task khác.
tổ chức chương trình vừa có các task theo time slice chạy liên tục vừa tổ chức
chương trình theo sự kiện có task ở trang thái block.
2.3.2 cấu hình cubemx
phần RCC, clock, uart (normal)
nên chọn time base khác system tick link giải thích
chọn freeRTOS, API CMSIS V2, và các thông số khác:
thêm task, thay đổi tên task, hàm, dung lượng, mức ưu tiên...
2.3.3 các hàm, thư viện
#include "cmsis_os.h"// thư viện
//tham số các task
osThreadId_t HIGH_TASKHandle;
const osThreadAttr_t HIGH_TASK_attributes = {
.name = "HIGH_TASK",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityAboveNormal,
};
/* Definitions for NORMAL_TASK */
osThreadId_t NORMAL_TASKHandle;
const osThreadAttr_t NORMAL_TASK_attributes = {
.name = "NORMAL_TASK",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for LOW_TASK */
osThreadId_t LOW_TASKHandle;
const osThreadAttr_t LOW_TASK_attributes = {
.name = "LOW_TASK",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityBelowNormal,
};
//hàm tự tạo cá nhân
void SEND_HIGH_TASK()
{
uint8_t data[] = "high taskrn";
HAL_UART_Transmit(&huart1, data, sizeof(data)-1, 100);
}
void SEND_NORMAL_TASK()
{
uint8_t data[] = "normal taskrn";
HAL_UART_Transmit(&huart1, data, sizeof(data)-1, 100);
}
void SEND_LOW_TASK()
{
uint8_t data[] = "low taskrn";
HAL_UART_Transmit(&huart1, data, sizeof(data)-1, 100);
}
//khởi tạo task
/* creation of HIGH_TASK */
HIGH_TASKHandle = osThreadNew(HIGH_F, NULL, &HIGH_TASK_attributes);
/* creation of NORMAL_TASK */
NORMAL_TASKHandle = osThreadNew(NORMAL_F, NULL, &NORMAL_TASK_attributes);
/* creation of LOW_TASK */
LOW_TASKHandle = osThreadNew(LOW_F, NULL, &LOW_TASK_attributes);
//khởi tạo kernel
osKernelStart();
2.3.4 VD chương trình
//hàm của các task
void HIGH_F(void *argument)
{
uint32_t tick = osKernelGetTickCount();
for(;;)
{
tick += 1000;
osDelayUntil(tick);
SEND_HIGH_TASK();
//osDelay(1);
}
}
void NORMAL_F(void *argument)
{
uint32_t tick = osKernelGetTickCount();
/* Infinite loop */
for(;;)
{
tick += 1000;
osDelayUntil(tick);
SEND_NORMAL_TASK();
//osDelay(1);
}
}
void LOW_F(void *argument)
{
uint32_t tick = osKernelGetTickCount();
/* Infinite loop */
for(;;)
{
tick += 1000;
osDelayUntil(tick);
SEND_LOW_TASK();
//osDelay(1);
}
}
3 task có mức ưu tiên khác nhau, cùng sử dụng chung uart, có dùng osDelayUntil
link vd chương trình
chu trình mỗi task: ready ↔ running→block→ready...
các vấn để: thời gian chuyển task tạm coi là nhỏ ko xét đến. thời gian thực hiện task
lớn hơn time slice nên bị ngắt task nhưng thời gian ready rồi trở lại running đủ nhỏ
nên vẫn ok. task sử dụng chung tài nguyên uart nhưng quản lý thời gian hợp lý nên
ko có xung đột tài nguyên.
2.4 Các vd để hiểu rõ hơn về time slice và preemption.
link video bài giảng của thầy
2.4.1 chương trình 1 (phút 3200
osdelay, osdelayUntil: thì sẽ có trạng thái block.
task cùng ưu tiên, thời gian thực thi trc khi block (osDelay) dài hơn 1 time slice⟶có
chuyển trạng thái giữa các time slice⟶ mỗi task chỉ thực thi 1 phần thì phải chuyển sang
cái khác (xung đột tài nguyên).
ví này mình không làm được, muốn in ra linh tinh nhưng nó ko in ra linh tinh (^ ^).
2.4.2 chương trình 2 (phút 45 00 đổ lại)
muốn cho công việc thực hiện đầy đủ
cần set lại mức ưu tiên cho các task, task sẽ chạy liên tục nhiều time slice, đến cuối vòng
for vô hạn gặp osdelay thị bị block, hết thời gian osdelay thì task lại ready trở lại, trong
thời gian block thì task khác thực hiện.
link project , chương trình main đc copy vào file chương trình 2.txt
nếu dùng osDelay:
high task 08; 10101018; 20202028; 30303038
normal task:1018; 10201028; 20302038; 30403048
low task 2048; 10501078; 20802108; 31103138
thời gian thực hiện low task nhiều hơn high task, ta thấy khoảng thời gian giữa kết thức
low task và bắt đầu high task ngày càng thu hẹp→ đến lúc nào đo sẽ có sự chồng lấn.
2.4.4 chương trình 4 (phút 5800 đổ lại)
muốn mốc thời gian ready→running fix cứng ko chồng nhau⟶ sử dụng delay until
high task 08; 10001008; 20002008; 30003008
normal task:1018; 10101018; 20102018; 30103018
low task 2048; 10201048; 20202048; 30203048
link project , chương trình main đc copy vào file chương trình 4.txt
2.4.5 chương trình 5
osthreadresume cho task vào ready
osthreadsuspend cho task vào suspend (treo-không hoạt động, dù task đó running hay
ready)
link project , chương trình main đc copy vào file chương trình 5.txt
chú ý chương trình của task chia làm 2 phần giống ardruino (setup thực hiện 1 lần và vòng
loop vô hạn). low task khi đc gọi lại thì hàm osUntilDelay so sánh giá trị trọng biến
tick=3000 với thời gian của HT hiện tại thì đã qua nên task ko bị block mà thực hiện tiếp
vòng for vô hạn, tick=4000..., tick=5000...→ thực hiện3 lần.
size của task nhỏ → tràn stack lẫn vào task→ chạy 1 lần→ không khôi phục đc.

More Related Content

PDF
FREERTOS_với_ESP32_IOTCHIP_GOODDDDDDDDDD
PDF
Rtos 4 queue vs interrupt
PDF
Stored procedure
PDF
Storedprocedure 140411073406-phpapp02
PPTX
Process and thread
DOC
Qtu.vn sql - chuong 7
PPT
Linux+04
PDF
Rtos 3 semaphore vs mutex
FREERTOS_với_ESP32_IOTCHIP_GOODDDDDDDDDD
Rtos 4 queue vs interrupt
Stored procedure
Storedprocedure 140411073406-phpapp02
Process and thread
Qtu.vn sql - chuong 7
Linux+04
Rtos 3 semaphore vs mutex

Similar to Rtos 2: time slice vs preeption (cùng mức ưu tiên vs có chiếm quyền (20)

PDF
Store procedure
DOC
Core java 8
 
PPT
Linux+02
DOC
Timer kernel linux
PPTX
BaoCaoFreeRTOS.pptx
PPTX
Free RTOS Porting CPU - ADKS
PDF
Thiet ke-he-thong-nhung -chuong-5-he-dieu-hanh-thoi-gian-thuc - [cuuduongthan...
PPTX
1 giới thiệu-cài đặt oracle
PPTX
1-Giới thiệu-cài đặt oracle chạy trên windows.pptx
PPTX
Chuong4_ConcurrencyChuong4_Concurrency.pptx
PPTX
Seminar clean code
PPTX
Bài thuyết trình môn học Hệ Điều Hành.pptx
DOCX
Bai bao cao 3
PPT
Virtual cluster thesis
PPTX
môn an toàn hệ điều hành bộ nhớ trong.pptx
DOC
Th linux
ODT
1.+tai+lieu+thiet+ke
PDF
RTOS 5 event vs notify
PPTX
How to write good code
PDF
Cach su dung Ubuntu
Store procedure
Core java 8
 
Linux+02
Timer kernel linux
BaoCaoFreeRTOS.pptx
Free RTOS Porting CPU - ADKS
Thiet ke-he-thong-nhung -chuong-5-he-dieu-hanh-thoi-gian-thuc - [cuuduongthan...
1 giới thiệu-cài đặt oracle
1-Giới thiệu-cài đặt oracle chạy trên windows.pptx
Chuong4_ConcurrencyChuong4_Concurrency.pptx
Seminar clean code
Bài thuyết trình môn học Hệ Điều Hành.pptx
Bai bao cao 3
Virtual cluster thesis
môn an toàn hệ điều hành bộ nhớ trong.pptx
Th linux
1.+tai+lieu+thiet+ke
RTOS 5 event vs notify
How to write good code
Cach su dung Ubuntu
Ad

Recently uploaded (20)

PDF
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 11 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
PDF
Bản phân loại thực vật môn thực vật dược
PDF
SÁNG KIẾN THIẾT KẾ MÔ HÌNH HỆ SINH THÁI HƯỚNG NGHIỆP CHO HỌC SINH THPT TRONG ...
PPT
Slide Nguyên lý bảo hiểm đại học knh tế quốc dân
DOCX
LUẬN VĂN GROUP ĐỀ BÀI ĐÁNH GIÁ GIAO TIẾP SƯ PHẠM
PPT
Bai 42 Su chay thanh dong cua chat long va chat khi Dinh luat Becnuli.ppt
PPTX
Chương3,Buổi7,8,9,10(Buổi10 kiểmtraL2).pptx
PDF
Sách không hôi fyjj ịuk gtyi yu> ướt jiii iiij
DOCX
Cao Thuy Linh-San pham cuoi khoa.- bồi dưỡng thường xuyêndocx
PDF
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 10 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
DOCX
Ôn tập Văn học phương đông tài liệu tham khảo
PPTX
24. 9cqbq2reu57m5igbsz-signature-40d40b8bd600bcde0d0584523c684ec4933c280de74a...
PDF
TUYỂN TẬP ĐỀ KIỂM TRA HÓA HỌC HỮU CƠ THI THỬ OLYMPIC HÓA HỌC QUỐC TẾ (VÒNG 2)...
DOCX
Chủ nghĩa xã hội khoa học - Đề Cương Cuối Kỳ.docx
PDF
Dao tao va Phat trien NỘI DUNG ÔN THI CHO SINH VIÊN
DOCX
Ôn tập văn học phương đông thi giữa kì ..
PDF
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 12 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
PDF
BÁO CÁO THỰC TẬP KỸ SƯ 2 ĐỀ TÀI TÌM HIỂU QUY TRÌNH CÔNG NGHỆ SẢN XUẤT BÁNH SN...
PDF
TeétOrganicChemistryFromVietNamVeryHardd
PDF
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 11 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 11 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
Bản phân loại thực vật môn thực vật dược
SÁNG KIẾN THIẾT KẾ MÔ HÌNH HỆ SINH THÁI HƯỚNG NGHIỆP CHO HỌC SINH THPT TRONG ...
Slide Nguyên lý bảo hiểm đại học knh tế quốc dân
LUẬN VĂN GROUP ĐỀ BÀI ĐÁNH GIÁ GIAO TIẾP SƯ PHẠM
Bai 42 Su chay thanh dong cua chat long va chat khi Dinh luat Becnuli.ppt
Chương3,Buổi7,8,9,10(Buổi10 kiểmtraL2).pptx
Sách không hôi fyjj ịuk gtyi yu> ướt jiii iiij
Cao Thuy Linh-San pham cuoi khoa.- bồi dưỡng thường xuyêndocx
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 10 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
Ôn tập Văn học phương đông tài liệu tham khảo
24. 9cqbq2reu57m5igbsz-signature-40d40b8bd600bcde0d0584523c684ec4933c280de74a...
TUYỂN TẬP ĐỀ KIỂM TRA HÓA HỌC HỮU CƠ THI THỬ OLYMPIC HÓA HỌC QUỐC TẾ (VÒNG 2)...
Chủ nghĩa xã hội khoa học - Đề Cương Cuối Kỳ.docx
Dao tao va Phat trien NỘI DUNG ÔN THI CHO SINH VIÊN
Ôn tập văn học phương đông thi giữa kì ..
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 12 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
BÁO CÁO THỰC TẬP KỸ SƯ 2 ĐỀ TÀI TÌM HIỂU QUY TRÌNH CÔNG NGHỆ SẢN XUẤT BÁNH SN...
TeétOrganicChemistryFromVietNamVeryHardd
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 11 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
Ad

Rtos 2: time slice vs preeption (cùng mức ưu tiên vs có chiếm quyền

  • 1. 2.1 RTOS RAM gồm vùng nhớ hệ thống và phần còn lại là vùng nhớ heap dành cho các task, mỗi task tương ứng với (stack, control block) heap_4 giúp chống phân mảnh, tận dụng vùng nhớ khi 1 task hoàn thành (giải phóng bộ nhớ). mỗi task tương ứng với 1 hàm thực thi, tham số task, bộ hàm của API của stm32 khác bộ hàm free RTOS, bộ hàm API CMSIS-v2 )có thể dùng cho nhiều nhiều hệ điều hành thời thực khác. link api 2.2 tổ chức chương trình theo chế độ chạy liên tục link video bài giảng của thầy về hàm printf, time slice, preemption 2.2.1 lý thuyết về chế độ chạy liên tục : yêu cầu: các task có mức ưu tiên bằng nhau, hàm thực thi là vòng lặp vô hạn. các task chỉ có 2 trang thái running-chạy và ready-'sẵn sàng để chạy' (task ở trong hàng đợi-theo cơ chế FIFO, ban đầu các task cùng ready, do cùng mức ưu tiên nên task nào được khởi tạo trc sẽ thoát chế độ ready và running trước (tại 1 thời điểm chỉ có tối đa 1 task running). task sẽ running trong thời gian là 1 time slice (1 ms), khi hết time slice thì task bị ngắt, nó sẽ chuyển từ running → ready (xếp vào cuối hàng đợi). tại mốc thời gian time slice sẽ có ngắt hệ thống của kernel (bộ lập lịch) lưu trạng thái của task trước và nạp trạng thái của task tiếp theo, task ready ở đầu hàng đợi sẽ được running. cứ như vậy thay các task thay phiên nhau running trong time slice của mình rồi lại ready.
  • 2. 2.2.2 hàm, thư viện sử dụng // thư viện #include "cmsis_os.h" //vd tham số, thuộc tính của task /* Definitions for NORMAL_TASK */ osThreadId_t NORMAL_TASKHandle; const osThreadAttr_t NORMAL_TASK_attributes = { .name = "NORMAL_TASK", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal, }; //khởi tạo bộ lập lịch kernel osKernelInitialize(); //vd khởi tạo các task (tên hàm, thuộc tính...) /* creation of defaultTask */ defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes); // bộ lập lịch bắt dầu chạy osKernelStart();
  • 3. 2.2.3 cấu hình CUBMX phần RCC, clock, GPIO làm như bình thường. nên chọn time base khác system tick link giải thích chọn FREERTOS, middware: CMSISV2 (api v1 hay v2, PREEMPTION (chiếm quyền), thời gian mỗi time_slice (TICK_RATE, minimal stack size (kích thước stack nhỏ nhất), queue registry size (kích thước hàng đợi), kích cỡ bộ nhớ heap, heap_4, .... //vd hàm thực thi của task /* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void *argument) { /* USER CODE BEGIN 5 */ uint16_t u1; /* Infinite loop */ for(;;) { HAL_GPIO_TogglePin(GPIOA, LED1_Pin); for(u1=0; u1<10000; u1++){ } //osDelay(1); } /* USER CODE END 5 */ }
  • 4. tạo task (tên task, mức ưu tiên, kích thước, tên hàm...)
  • 5. 2.2.4 VD chương trình: các task cùng mức ưu tiên, ko dùng osDelay trong vòng lặp vô hạn, thực hiện nháy led. khi đó task sẽ lần lượt vào các trạng thái: ready3→ready2→ready1→running- >ready3... các vấn để: thời gian chuyển task tạm coi là nhỏ. thời gian thực hiện task lớn hơn time slice nên task bị ngắt khi tới time slice nhưng thời gian ready rồi trở lại running trong khoảng thời gian đủ nhỏ . sử dụng 3 led khác nhau nên ko xung đột tài nguyên. link ví dụ 2.3 tổ chức chương trình theo sự kiện (task có mức ưu tiên). link video bài giảng của thầy về hàm printf, time slice, preemption
  • 6. 2.3.1 lý thuyết ban đầu khi các task ở trạng thái ready (trong hàng đợi), do các task có mức ưu tiên khác nhau nên task nào có mức ưu tiên cao nhất thì sẽ running trước. khi đến time slice thì task đó trở lại trang thái ready. Nhưng khi so sánh mức ưu tiên của các task đang ready thì nó vẫn là task có mức ưu tiên cao nhất nên tiếp tục running. Cứ như vậy task có mức ưu tiên cao nhất chiếm hết thời gian hệ thống. muốn tránh task có mức ưu tiên cao nhất chiếm hết thời gian hệ thống, thì ta có thể dùng hàm osDelay. khi đó task có mức ưu tiên cao sẽ rơi vào trang thái block, task có mức ưu tiên thấp hơn khác có cơ hội được thực hiện. sau 1 khoảng thời gian osDelay thì task bị block sẽ chuyền về ready và có thể running.
  • 7. một cách delay khác đó là delay theo mốc thời gian: 1 task có thể cầu hình lại mức ưu tiên của task khác __IO uint32_t tick2 = osKernelGetTichCount(); tick2+=500; //do something osDelayUntil(tich2);
  • 8. 1 task tạo ra 1 task khác, rồi task thậm chí xoá chính nó,
  • 9. một task có thể suspended task khác. tổ chức chương trình vừa có các task theo time slice chạy liên tục vừa tổ chức chương trình theo sự kiện có task ở trang thái block. 2.3.2 cấu hình cubemx phần RCC, clock, uart (normal) nên chọn time base khác system tick link giải thích chọn freeRTOS, API CMSIS V2, và các thông số khác:
  • 10. thêm task, thay đổi tên task, hàm, dung lượng, mức ưu tiên...
  • 11. 2.3.3 các hàm, thư viện #include "cmsis_os.h"// thư viện //tham số các task osThreadId_t HIGH_TASKHandle; const osThreadAttr_t HIGH_TASK_attributes = { .name = "HIGH_TASK", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityAboveNormal, }; /* Definitions for NORMAL_TASK */ osThreadId_t NORMAL_TASKHandle; const osThreadAttr_t NORMAL_TASK_attributes = { .name = "NORMAL_TASK", .stack_size = 128 * 4,
  • 12. .priority = (osPriority_t) osPriorityNormal, }; /* Definitions for LOW_TASK */ osThreadId_t LOW_TASKHandle; const osThreadAttr_t LOW_TASK_attributes = { .name = "LOW_TASK", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityBelowNormal, }; //hàm tự tạo cá nhân void SEND_HIGH_TASK() { uint8_t data[] = "high taskrn"; HAL_UART_Transmit(&huart1, data, sizeof(data)-1, 100); } void SEND_NORMAL_TASK() { uint8_t data[] = "normal taskrn"; HAL_UART_Transmit(&huart1, data, sizeof(data)-1, 100); } void SEND_LOW_TASK() { uint8_t data[] = "low taskrn"; HAL_UART_Transmit(&huart1, data, sizeof(data)-1, 100); } //khởi tạo task /* creation of HIGH_TASK */ HIGH_TASKHandle = osThreadNew(HIGH_F, NULL, &HIGH_TASK_attributes); /* creation of NORMAL_TASK */ NORMAL_TASKHandle = osThreadNew(NORMAL_F, NULL, &NORMAL_TASK_attributes); /* creation of LOW_TASK */ LOW_TASKHandle = osThreadNew(LOW_F, NULL, &LOW_TASK_attributes); //khởi tạo kernel osKernelStart();
  • 13. 2.3.4 VD chương trình //hàm của các task void HIGH_F(void *argument) { uint32_t tick = osKernelGetTickCount(); for(;;) { tick += 1000; osDelayUntil(tick); SEND_HIGH_TASK(); //osDelay(1); } } void NORMAL_F(void *argument) { uint32_t tick = osKernelGetTickCount(); /* Infinite loop */ for(;;) { tick += 1000; osDelayUntil(tick); SEND_NORMAL_TASK(); //osDelay(1); } } void LOW_F(void *argument) { uint32_t tick = osKernelGetTickCount(); /* Infinite loop */ for(;;) { tick += 1000; osDelayUntil(tick); SEND_LOW_TASK(); //osDelay(1); } }
  • 14. 3 task có mức ưu tiên khác nhau, cùng sử dụng chung uart, có dùng osDelayUntil link vd chương trình chu trình mỗi task: ready ↔ running→block→ready... các vấn để: thời gian chuyển task tạm coi là nhỏ ko xét đến. thời gian thực hiện task lớn hơn time slice nên bị ngắt task nhưng thời gian ready rồi trở lại running đủ nhỏ nên vẫn ok. task sử dụng chung tài nguyên uart nhưng quản lý thời gian hợp lý nên ko có xung đột tài nguyên. 2.4 Các vd để hiểu rõ hơn về time slice và preemption. link video bài giảng của thầy 2.4.1 chương trình 1 (phút 3200 osdelay, osdelayUntil: thì sẽ có trạng thái block. task cùng ưu tiên, thời gian thực thi trc khi block (osDelay) dài hơn 1 time slice⟶có chuyển trạng thái giữa các time slice⟶ mỗi task chỉ thực thi 1 phần thì phải chuyển sang cái khác (xung đột tài nguyên). ví này mình không làm được, muốn in ra linh tinh nhưng nó ko in ra linh tinh (^ ^). 2.4.2 chương trình 2 (phút 45 00 đổ lại) muốn cho công việc thực hiện đầy đủ cần set lại mức ưu tiên cho các task, task sẽ chạy liên tục nhiều time slice, đến cuối vòng for vô hạn gặp osdelay thị bị block, hết thời gian osdelay thì task lại ready trở lại, trong thời gian block thì task khác thực hiện. link project , chương trình main đc copy vào file chương trình 2.txt nếu dùng osDelay: high task 08; 10101018; 20202028; 30303038 normal task:1018; 10201028; 20302038; 30403048 low task 2048; 10501078; 20802108; 31103138 thời gian thực hiện low task nhiều hơn high task, ta thấy khoảng thời gian giữa kết thức low task và bắt đầu high task ngày càng thu hẹp→ đến lúc nào đo sẽ có sự chồng lấn. 2.4.4 chương trình 4 (phút 5800 đổ lại) muốn mốc thời gian ready→running fix cứng ko chồng nhau⟶ sử dụng delay until high task 08; 10001008; 20002008; 30003008
  • 15. normal task:1018; 10101018; 20102018; 30103018 low task 2048; 10201048; 20202048; 30203048 link project , chương trình main đc copy vào file chương trình 4.txt 2.4.5 chương trình 5 osthreadresume cho task vào ready osthreadsuspend cho task vào suspend (treo-không hoạt động, dù task đó running hay ready) link project , chương trình main đc copy vào file chương trình 5.txt chú ý chương trình của task chia làm 2 phần giống ardruino (setup thực hiện 1 lần và vòng loop vô hạn). low task khi đc gọi lại thì hàm osUntilDelay so sánh giá trị trọng biến tick=3000 với thời gian của HT hiện tại thì đã qua nên task ko bị block mà thực hiện tiếp vòng for vô hạn, tick=4000..., tick=5000...→ thực hiện3 lần. size của task nhỏ → tràn stack lẫn vào task→ chạy 1 lần→ không khôi phục đc.