作業系統工程 Operating System Programming note
, 110-1
, 2021
- rt_signal_mask
- 信號阻塞,也可以理解為屏蔽信號。
若該信號被阻塞,則該信號將不會遞達給安裝此信號的線程,也不會引發 soft interrupt。
#include <rtthread.h>
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
static rt_thread_t tid1 = RT_NULL;
// thread 1 的信號處裡函数
void thread1_signal_handler(int sig)
{
rt_kprintf("thread1 received signal %d\n", sig);
return;
}
// kernal 中,在 signal.c 也有預設的 signal_handler
//
//static void _signal_default_handler(int signo)
//{
// LOG_I("handled signo[%d] with default action.", signo);
// return ;
//}
//
// thread 1 的入口函数
static void thread1_entry(void *parameter)
{
int cnt = 0;
// set up signal
rt_signal_install(SIGUSR1, thread1_signal_handler);
rt_signal_unmask(SIGUSR1);
while(/*不斷的去偵測卡球的情況有沒有發生*/)
{
rt_thread_kill(tid2, SIGUSR1);
// 若發現有卡球的情況發生,就發送信號 SIGUSR1 给 thread 2 去處理
}
}
/* thread 2 的入口函数 */
static void thread2_entry(void *parameter)
{
int cnt = 0;
// set up signal
rt_signal_install(SIGUSR1, thread1_signal_handler);
rt_signal_unmask(SIGUSR1);
/* 增加底部馬達的轉動力度 */
/// Code
}
int _sample(void)
{
// 產生thread 1
tid1 = rt_thread_create("thread1", thread1_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIO, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
// 產生thread 2
tid2 = rt_thread_create("thread2", thread2_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIO, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
return 0;
}
// 导出到 msh 命令列表中
MSH_CMD_EXPORT(signal_sample, signal sample);
#include <rtthread.h>
#define THREAD_PRIORITY 10
#define THREAD_TIMESLICE 5
static struct rt_mailbox mb;
/* 用於放 mail 的 memory pool */
static char mb_pool[128];
static char mb_str1[] = "type 1 error";
static char mb_str2[] = "type 2 error";
static char mb_str3[] = "over";
ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;
/* thread 1 入口 */
static void thread1_entry(void *parameter)
{
char *str;
while (1)
{
rt_kprintf("thread1: try to recv a mail\n");
// 從 mailbox 中收 mail
if (rt_mb_recv(&mb, (rt_uint32_t *)&str, RT_WAITING_FOREVER) == RT_EOK)
{
rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str);
if (str == mb_str1)
{
// call 對應得 function 處理對應的 error
}
else if (str == mb_str2)
{
// call 對應得 function 處理對應的 error
}
else if (str == mb_str3)
break;
// delay 100ms
rt_thread_mdelay(100);
}
}
// 讓 mailbox 上的 object 脫離
rt_mb_detach(&mb);
}
ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
// thread 2 入口
// 負責發送 mail (各種 error type)到 mailbox
rt_uint8_t _error_type;
static void thread2_entry(void *parameter)
{
while (_error_type < 10)
{
_error_type ++;
if (_error_type & 0x1)
{
/* 發送 mb_str1 地址到 mailbox 中 */
rt_mb_send(&mb, (rt_uint32_t)&mb_str1);
}
else
{
/* 發送 mb_str2 地址到 mailbox 中 */
rt_mb_send(&mb, (rt_uint32_t)&mb_str2);
}
/* delay 200ms */
rt_thread_mdelay(200);
}
// thread 3 代表運行結束的字串
// 發送 mail 告诉 thread 1,thread 2 已经運行结束
rt_mb_send(&mb, (rt_uint32_t)&mb_str3);
}
int mailbox_sample(void)
{
rt_err_t result;
// 初始化 mailbox
// 名稱是 mbt, mailbox 用到的 memory pool 是 mb_pool, mailbox 中的郵件數目,因为一封 mail 為 4 bytes, 用 PRIORITY 的方式做 processes waiting
result = rt_mb_init(&mb, "mbt", &mb_pool[0], sizeof(mb_pool)/4, RT_IPC_FLAG_PRIO);
if (result != RT_EOK)
{
rt_kprintf("init mailbox failed.\n");
return -1;
}
//初始化 thread 1,並啟動他
rt_thread_init(&thread1, "thread1", thread1_entry, RT_NULL, &thread1_stack[0], sizeof(thread1_stack), THREAD_PRIORITY, THREAD_TIMESLICE);
rt_thread_startup(&thread1);
//初始化 thread 2,並啟動他
rt_thread_init(&thread2, "thread2", thread2_entry, RT_NULL, &thread2_stack[0], sizeof(thread2_stack), THREAD_PRIORITY, THREAD_TIMESLICE);
rt_thread_startup(&thread2);
return 0;
}
int main(void)
{
/*int count = 1;
while (count++)
{
LOG_D("Hello RT-Thread!");
rt_thread_mdelay(1000);
}*/
rt_uint32_t period, pulse, dir;
period = 500000; // 周期为0.5ms,单位为纳秒ns
dir = 1; // PWM脉冲宽度值的增减方向
pulse = 0; // PWM脉冲宽度值,单位为纳秒ns
// 找 device
pwm_dev = (struct rt_device_pwm *) rt_device_find(PWM_DEV_NAME);
if (pwm_dev == RT_NULL)
{
rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
return RT_ERROR;
}
// 设置PWM周期和脉冲宽度默认值
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
// 使能设备
rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
int count = 0;
while (count < 10)
{
rt_thread_mdelay(1000);
if (dir)
{
pulse += 5000; // 从0值开始每次增加5000ns
}
else
{
pulse -= 5000; // 从最大值开始每次减少5000ns
}
if (pulse >= period)
{
dir = 0;
}
if (0 == pulse)
{
dir = 1;
}
// 设置PWM周期和脉冲宽度
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
count++;
}
return RT_EOK;
}
> RT-Thread 中,時鐘節拍的長度可以根據RT_TICK_PER_SECOND 的定義來調整,等於1/RT_TICK_PER_SECOND 秒。
> # Semaphone/ mutex application
Contents Background 為何要有 Virtual memory 程式在被 CPU 執行之前,必須先把程式的內容載入到到一段 連續的記憶體空間 如此一來 CPU 才能根據記憶體中的的程式一行一行執行下去 同時開啟很多應用程式時,記憶體會長的像下面這樣 之後每當有新啟動的程式,系統就會從剩餘的記憶體中分配一段 連續的空間 給他,而若有程式結束了,那系統也會把他佔用的記憶體清除掉
Apr 8, 2024understanding of verilog(Chinese) hackmd link Final HW-System chip implementation hackmd link My design decode mode instruction set
Nov 15, 2023multiplication in midterm hackmd link code_ RISC-V-rv32IRJCore github link 測試 Instruction Fetch hackmd link ROM 和 RegsFile
Nov 15, 2023OS-Chap1 - Introduction OS-Chap2 - OS Structure(OS結構) OS-Chap3 - Process_行程 OS-Chap5 - CPU scheduling OS-Chap6 - Synchonization OS-Chap7 - Deadlock_死結 OS-Chap8 - Memory Management_記憶體管理 OS-Chap9 - Virtual Memory_虛擬記憶體 OS-Chap12 - I/O systems_
Nov 10, 2023or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up