1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-09-25     tangzz98     the first version
9  */
10 
11 #include <rtthread.h>
12 #include <mprotect.h>
13 
14 #define THREAD_PRIORITY      25
15 #define THREAD_STACK_SIZE    512
16 #define THREAD_TIMESLICE     5
17 
rt_align(MPU_MIN_REGION_SIZE)18 rt_align(MPU_MIN_REGION_SIZE) rt_uint8_t thread1_private_data[MPU_MIN_REGION_SIZE];
19 
20 static void thread1_entry(void *parameter)
21 {
22     (void)parameter;
23     /* Thread 1 configures thread1_private_data for exclusive access */
24     rt_kprintf("Thread 1 configures private data\n");
25     rt_mprotect_add_exclusive_region((void *)thread1_private_data, MPU_MIN_REGION_SIZE);
26     rt_kprintf("Thread 1 private data address: %p - %p\n", &thread1_private_data[0], &thread1_private_data[MPU_MIN_REGION_SIZE]);
27     rt_kprintf("Thread 1 reads and writes to its private data\n");
28     for (int i = 0; i < MPU_MIN_REGION_SIZE; i++)
29     {
30         /* Thread 1 has access to its private data */
31         thread1_private_data[i] = i;
32         rt_kprintf("thread1_private_data[%d] = %d\n", i, thread1_private_data[i]);
33     }
34 }
35 
thread2_entry(void * parameter)36 static void thread2_entry(void *parameter)
37 {
38     (void)parameter;
39     rt_kprintf("Thread 2 writes to thread 1's private data\n");
40     for (int i = 0; i < MPU_MIN_REGION_SIZE; i++)
41     {
42         /*
43          * Thread 2 does not have access to thread 1's private data.
44          * Access generates an exception.
45          */
46         thread1_private_data[i] = i;
47     }
48 }
49 
mprotect_example_exclusive_region()50 int mprotect_example_exclusive_region()
51 {
52     extern void mprotect_example_exception_hook(rt_mem_exception_info_t *info);
53     rt_hw_mpu_exception_set_hook(mprotect_example_exception_hook);
54     rt_thread_t tid1 = RT_NULL;
55     tid1 = rt_thread_create("thread1",
56                            thread1_entry, RT_NULL,
57                            THREAD_STACK_SIZE,
58                            THREAD_PRIORITY - 1,
59                            THREAD_TIMESLICE);
60     if (tid1 != RT_NULL)
61         rt_thread_startup(tid1);
62 
63     rt_thread_t tid2 = RT_NULL;
64     tid2 = rt_thread_create("thread2",
65                            thread2_entry, RT_NULL,
66                            THREAD_STACK_SIZE,
67                            THREAD_PRIORITY,
68                            THREAD_TIMESLICE);
69     if (tid2 != RT_NULL)
70         rt_thread_startup(tid2);
71 
72     return 0;
73 }
74 
75 MSH_CMD_EXPORT(mprotect_example_exclusive_region, Memory protection example (exclusive_region));
76