Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
mo动态模块_Module
原创征文
RT-Thread动态模块mo调试设备驱动小结【mo实现linux中ko功能】
发布于 2023-08-05 16:42:10 浏览:1151
订阅该版
[tocm] # 前言 动态驱动模块的调试可以减少烧录过程,对于调试来说是一件很快乐的事情。 rtt中有动态模块概念,而且和linux中的命名类似为分为mo和so,其中mo在笔者浅显的理解即类似于linux中的elf,即可执行文件。同时linux中的ko也是elf文件一种,所以想rtt中的mo和linux中的ko是否可以实现同样的功能。以下以uart串口驱动模块的动态加载调试作为示例讲解整个操作流程。 # 正文 ## 准备步骤 首先是准备步骤:搭建环境,编译生成mo。这里可以参考RT_Thread编程指南中的28节 动态模块章节,使用过程中注意linux环境中也需要设置环境变量(RTT_ROOT、BSP_ROOT)。 我这里使用的是github仓库中的hello模块。编译生成hello.mo,在msh中执行hello,输出hello,这一步工作完成。 ## 编译驱动mo 接下来是编译生成uart的设备驱动,并且注册到rtt的设备驱动管理框架中。 以下是hello.c中的代码,代码比较多,截取了主要部分,因为针对于不同平台的串口初始化函数是不一样的。 在main中调用rt_hw_uart_init();实现对串口驱动的注册。 ```c int rt_hw_uart_init(void) { struct rt_serial_device *serial; struct device_uart *uart; struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; static struct rt_serial_device serial1; static struct device_uart uart1; serial = &serial1; uart = &uart1; serial->ops = &_uart_ops; serial->config = config; serial->config.baud_rate = 115200; rt_hw_serial_register(serial, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); return 0; } int main(int argc, char *argv[]) { printf("hello world from RTT::dynamic module\n"); rt_hw_uart_init(); return 0; } ``` 这里会出现两个问题: ### 问题一:动态模块加载缺少函数符号问题 https://club.rt-thread.org/ask/question/50d4b6f786494c42.html ### 问题二:动态驱动模块加载报错【rt_object_init】是否存在bug? https://club.rt-thread.org/ask/question/e91fa988b2da9c7c.html 以上是针对两个问题的解决方式。具体问题和解决方案请查看文章内容。 针对问题二做一下补充说明 ```c #ifdef RT_USING_MODULE if (module) { if(rt_strcmp(object->name,"uart1") == 0) { rt_list_insert_after(&(information->object_list), &(object->list)); object->module_id = (void *)module; } else { rt_list_insert_after(&(module->object_list), &(object->list)); object->module_id = (void *)module; } } else #endif /* RT_USING_MODULE */ { /* insert object into information object list */ rt_list_insert_after(&(information->object_list), &(object->list)); } ``` 这里 if(rt_strcmp(object->name,"uart1") == 0)比较的设备是uart1,如果你的hello.c中的注册设备是其他记得修改 这里,同时这里也是一个极其不合理的存在。正在思考如何修改 编译执行完后,在msh执行hello.c,使用指令list_device可以观察到存在uart1设备,说明运行成功。 ![屏幕截图 2023-08-03 153951.png](https://oss-club.rt-thread.org/uploads/20230805/6ba78559fe34d1022d0844737301b2b0.png) ### 测试驱动是否正常 编写串口测试程序 ```c /* * Program list: This is a uart device usage routine * The routine exports the uart_sample command to the control terminal * Format of command: uart_sample uart2 * Command explanation: the second parameter of the command is the name of the uart device. If it is null, the default uart device wil be used * Program function: output the string "hello RT-Thread!" through the serial port, and then malposition the input character */ #include
#define SAMPLE_UART_NAME "uart1" /* Semaphore used to receive messages */ static struct rt_semaphore rx_sem; static rt_device_t serial; /* Receive data callback function */ static rt_err_t uart_input(rt_device_t dev, rt_size_t size) { /* After the uart device receives the data, it generates an interrupt, calls this callback function, and then sends the received semaphore. */ rt_sem_release(&rx_sem); return RT_EOK; } static void serial_thread_entry(void *parameter) { char ch; while (1) { /* Read a byte of data from the serial port and wait for the receiving semaphore if it is not read */ while (rt_device_read(serial, -1, &ch, 1) != 1) { /* Being Suspended and waiting for the semaphore */ rt_sem_take(&rx_sem, RT_WAITING_FOREVER); } /* Read the data from the serial port and output through dislocation */ ch = ch + 1; rt_device_write(serial, 0, &ch, 1); } } static int uart_sample(int argc, char *argv[]) { rt_err_t ret = RT_EOK; char uart_name[RT_NAME_MAX]; char str[] = "hello RT-Thread!\r\n"; if (argc == 2) { rt_strncpy(uart_name, argv[1], RT_NAME_MAX); } else { rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); } /* Find uart devices in the system */ serial = rt_device_find(uart_name); if (!serial) { rt_kprintf("find %s failed!\n", uart_name); return RT_ERROR; } /* Initialize the semaphore */ rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); /* Open the uart device in interrupt receive and polling send mode */ rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); /* Set the receive callback function */ rt_device_set_rx_indicate(serial, uart_input); /* Send string */ rt_device_write(serial, 0, str, (sizeof(str) - 1)); /* Create a serial thread */ rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); /* Start the thread successfully */ if (thread != RT_NULL) { rt_thread_startup(thread); } else { ret = RT_ERROR; } return ret; } /* Export to the msh command list */ MSH_CMD_EXPORT(uart_sample, uart device sample); ``` 在msh中输入uart_sample,驱动打开,初始化正常。观察uart1工作是否正常。正常说明驱动加载运行正常。
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
黑海大白鲨
这家伙很懒,什么也没写!
文章
2
回答
3
被采纳
0
关注TA
发私信
相关文章
1
貌似stm32f10x的应用模块在1.2.x版本不能正常编译
2
应用模块打开之后unload之后还在内存中
3
关于module.c的_load_shared_object的疑问
4
应用模块的rt_module_unload函数的bug
5
rtt 如何实现动态加载app
6
使用zmodem传输文件,应用模块文件传输完成,访问失败
7
RTT下应用模块编译具体方法
8
RTT应用模块编译出错
9
RTT应用模块编译问题
10
求问动态模块是什么意思呢
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
xusiwei1236
8
个答案
2
次被采纳
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
9
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
RTT_逍遥
3
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
4
次点赞
Ghost_Girls
1
篇文章
6
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部