1 /* ram_console.c - Console messages to a RAM buffer */ 2 3 /* 4 * Copyright (c) 2015 Intel Corporation 5 * Copyright 2024-2025 NXP 6 * 7 * SPDX-License-Identifier: Apache-2.0 8 */ 9 10 11 #include <zephyr/kernel.h> 12 #include <zephyr/sys/printk.h> 13 #include <zephyr/sys/printk-hooks.h> 14 #include <zephyr/sys/libc-hooks.h> 15 #include <zephyr/device.h> 16 #include <zephyr/init.h> 17 #include <zephyr/linker/devicetree_regions.h> 18 19 #ifdef CONFIG_RAM_CONSOLE_BUFFER_SECTION 20 #if !DT_HAS_CHOSEN(zephyr_ram_console) 21 #error "Lack of chosen property zephyr,ram_console!" 22 #elif (CONFIG_RAM_CONSOLE_BUFFER_SIZE > DT_REG_SIZE(DT_CHOSEN(zephyr_ram_console))) 23 #error "Custom RAM console buffer exceeds the section size!" 24 #endif 25 26 #define RAM_CONSOLE_BUF_ATTR \ 27 __attribute__((__section__(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ram_console))))) 28 #else 29 #define RAM_CONSOLE_BUF_ATTR 30 #endif 31 32 /* workaround the fact that device_map() is not defined for SoCs with no MMU */ 33 #ifndef DEVICE_MMIO_IS_IN_RAM 34 #define device_map(virt, phys, size, flags) *(virt) = (phys) 35 #endif /* DEVICE_MMIO_IS_IN_RAM */ 36 37 char ram_console_buf[CONFIG_RAM_CONSOLE_BUFFER_SIZE] RAM_CONSOLE_BUF_ATTR; 38 char *ram_console; 39 static int pos; 40 ram_console_out(int character)41static int ram_console_out(int character) 42 { 43 ram_console[pos] = (char)character; 44 /* Leave one byte to ensure we're always NULL-terminated */ 45 pos = (pos + 1) % (CONFIG_RAM_CONSOLE_BUFFER_SIZE - 1); 46 return character; 47 } 48 ram_console_init(void)49static int ram_console_init(void) 50 { 51 #ifdef CONFIG_RAM_CONSOLE_BUFFER_SECTION 52 mm_reg_t ram_console_va; 53 54 device_map((mm_reg_t *)&ram_console_va, DT_REG_ADDR(DT_CHOSEN(zephyr_ram_console)), 55 CONFIG_RAM_CONSOLE_BUFFER_SIZE, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); 56 ram_console = (char *)ram_console_va; 57 #else 58 ram_console = ram_console_buf; 59 #endif 60 __printk_hook_install(ram_console_out); 61 __stdout_hook_install(ram_console_out); 62 63 return 0; 64 } 65 66 SYS_INIT(ram_console_init, PRE_KERNEL_1, CONFIG_CONSOLE_INIT_PRIORITY); 67