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 ro_data[MPU_MIN_REGION_SIZE];
19 
20 static void thread1_entry(void *parameter)
21 {
22     (void)parameter;
23     rt_kprintf("ro_data address: %p - %p\n", &ro_data[0], &ro_data[MPU_MIN_REGION_SIZE]);
24     /* Thread 1 can write ro_data before configuring memory protection. */
25     rt_kprintf("Thread 1 writes to ro_data before configuring memory protection\n");
26     for (int i = 0; i < MPU_MIN_REGION_SIZE; i++)
27     {
28         ro_data[i] = i;
29         rt_kprintf("ro_data[%d] = %d\n", i, ro_data[i]);
30     }
31     rt_mem_region_t ro_region =
32     {
33         .start = (void *)ro_data,
34         .size = MPU_MIN_REGION_SIZE,
35         .attr = RT_MEM_REGION_P_RO_U_RO,
36     };
37     /* Thread 1 configures ro_data as read only. */
38     rt_kprintf("Thread 1 configures ro_data for read-only access for thread 1\n");
39     rt_mprotect_add_region(RT_NULL, &ro_region);
40     rt_kprintf("Thread 1 reads ro_data\n");
41     for (int i = 0; i < MPU_MIN_REGION_SIZE; i++)
42     {
43         rt_kprintf("ro_data[%d] = %d\n", i, ro_data[i]);
44     }
45     rt_thread_delay(RT_TICK_PER_SECOND * 1);
46     /* Thread 1 cannot write ro_data. */
47     rt_kprintf("Thread 1 writes to ro_data\n");
48     for (int i = 0; i < MPU_MIN_REGION_SIZE; i++)
49     {
50         ro_data[i] = i;
51     }
52 }
53 
thread2_entry(void * parameter)54 static void thread2_entry(void *parameter)
55 {
56     (void)parameter;
57     rt_kprintf("Thread 2 writes to ro_data\n");
58     for (int i = 0; i < MPU_MIN_REGION_SIZE; i++)
59     {
60         /* Thread 2 can write ro_data. */
61         ro_data[i] = i;
62         rt_kprintf("ro_data[%d] = %d\n", i, ro_data[i]);
63     }
64 }
65 
mprotect_example_ro_data()66 int mprotect_example_ro_data()
67 {
68     extern void mprotect_example_exception_hook(rt_mem_exception_info_t *info);
69     rt_hw_mpu_exception_set_hook(mprotect_example_exception_hook);
70     rt_thread_t tid1 = RT_NULL;
71     tid1 = rt_thread_create("thread1",
72                            thread1_entry, RT_NULL,
73                            THREAD_STACK_SIZE,
74                            THREAD_PRIORITY - 1,
75                            THREAD_TIMESLICE);
76     rt_thread_startup(tid1);
77     rt_thread_t tid2 = RT_NULL;
78     tid2 = rt_thread_create("thread2",
79                            thread2_entry, RT_NULL,
80                            THREAD_STACK_SIZE,
81                            THREAD_PRIORITY,
82                            THREAD_TIMESLICE);
83     rt_thread_startup(tid2);
84 
85     return 0;
86 }
87 
88 MSH_CMD_EXPORT(mprotect_example_ro_data, Memory protection example (read-only data));
89