0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

RT-Thread動(dòng)態(tài)模塊mo調(diào)試設(shè)備驅(qū)動(dòng)小結(jié)

冬至子 ? 來源:黑海大白鯊 ? 作者:黑海大白鯊 ? 2023-08-07 14:46 ? 次閱讀

前言
動(dòng)態(tài)驅(qū)動(dòng)模塊的調(diào)試可以減少燒錄過程,對于調(diào)試來說是一件很快樂的事情。
rtt中有動(dòng)態(tài)模塊概念,而且和linux中的命名類似為分為mo和so,其中mo在筆者淺顯的理解即類似于linux中的elf,即可執(zhí)行文件。同時(shí)linux中的ko也是elf文件一種,所以想rtt中的mo和linux中的ko是否可以實(shí)現(xiàn)同樣的功能。以下以uart串口驅(qū)動(dòng)模塊的動(dòng)態(tài)加載調(diào)試作為示例講解整個(gè)操作流程。

正文
準(zhǔn)備步驟
首先是準(zhǔn)備步驟:搭建環(huán)境,編譯生成mo。這里可以參考RT_Thread編程指南中的28節(jié) 動(dòng)態(tài)模塊章節(jié),使用過程中注意linux環(huán)境中也需要設(shè)置環(huán)境變量(RTT_ROOT、BSP_ROOT)。
我這里使用的是github倉庫中的hello模塊。編譯生成hello.mo,在msh中執(zhí)行hello,輸出hello,這一步工作完成。

編譯驅(qū)動(dòng)mo
接下來是編譯生成uart的設(shè)備驅(qū)動(dòng),并且注冊到rtt的設(shè)備驅(qū)動(dòng)管理框架中。
以下是hello.c中的代碼,代碼比較多,截取了主要部分,因?yàn)獒槍τ诓煌脚_的串口初始化函數(shù)是不一樣的。
在main中調(diào)用rt_hw_uart_init();實(shí)現(xiàn)對串口驅(qū)動(dòng)的注冊。

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 modulen");
rt_hw_uart_init();
return 0;
}
這里會(huì)出現(xiàn)兩個(gè)問題:

問題一:動(dòng)態(tài)模塊加載缺少函數(shù)符號問題

問題二:動(dòng)態(tài)驅(qū)動(dòng)模塊加載報(bào)錯(cuò)【rt_object_init】是否存在bug?

以上是針對兩個(gè)問題的解決方式。

針對問題二做一下補(bǔ)充說明

#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)比較的設(shè)備是uart1,如果你的hello.c中的注冊設(shè)備是其他記得修改

這里,同時(shí)這里也是一個(gè)極其不合理的存在。正在思考如何修改

編譯執(zhí)行完后,在msh執(zhí)行hello.c,使用指令list_device可以觀察到存在uart1設(shè)備,說明運(yùn)行成功。

1.jpg

測試驅(qū)動(dòng)是否正常
編寫串口測試程序

/*

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!rn";
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,驅(qū)動(dòng)打開,初始化正常。觀察uart1工作是否正常。正常說明驅(qū)動(dòng)加載運(yùn)行正常。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 調(diào)試器
    +關(guān)注

    關(guān)注

    1

    文章

    297

    瀏覽量

    23568
  • 串口驅(qū)動(dòng)
    +關(guān)注

    關(guān)注

    2

    文章

    81

    瀏覽量

    18501
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    315

    瀏覽量

    21556
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1239

    瀏覽量

    39430
  • Uart串口
    +關(guān)注

    關(guān)注

    0

    文章

    29

    瀏覽量

    6767
收藏 人收藏

    評論

    相關(guān)推薦

    RT-Thread記錄(九、RTT中斷處理與階段小結(jié)

    RT-Thread 內(nèi)核部分最后一個(gè)點(diǎn) 中斷管理,順帶著對前面所學(xué)知識做個(gè)小結(jié)
    的頭像 發(fā)表于 06-24 10:25 ?5964次閱讀
    <b class='flag-5'>RT-Thread</b>記錄(九、RTT中斷處理與階段<b class='flag-5'>小結(jié)</b>)

    RT-Thread ssd1306驅(qū)動(dòng)

    RT-Thread 驅(qū)動(dòng)ssd1306
    的頭像 發(fā)表于 04-21 10:08 ?26.4w次閱讀
    <b class='flag-5'>RT-Thread</b> ssd1306<b class='flag-5'>驅(qū)動(dòng)</b>

    RT-Thread設(shè)備驅(qū)動(dòng)開發(fā)指南基礎(chǔ)篇—以先楫bsp的hwtimer設(shè)備為例

    RT-Thread設(shè)備驅(qū)動(dòng)開發(fā)指南》書籍是RT-thread官方出品撰寫,系統(tǒng)講解RT-thread IO
    的頭像 發(fā)表于 02-20 16:01 ?1407次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>設(shè)備</b><b class='flag-5'>驅(qū)動(dòng)</b>開發(fā)指南基礎(chǔ)篇—以先楫bsp的hwtimer<b class='flag-5'>設(shè)備</b>為例

    RT-Thread Studio驅(qū)動(dòng)SD卡

    RT-Thread Studio驅(qū)動(dòng)SD卡前言一、創(chuàng)建基本工程1、創(chuàng)建Bootloader2、創(chuàng)建項(xiàng)目工程二、配置RT-Thread Settings三、代碼分析1.引入庫2.讀入數(shù)據(jù)四、效果驗(yàn)證
    發(fā)表于 12-27 19:13 ?20次下載
    <b class='flag-5'>RT-Thread</b> Studio<b class='flag-5'>驅(qū)動(dòng)</b>SD卡

    RT-Thread文檔_RT-Thread 簡介

    RT-Thread文檔_RT-Thread 簡介
    發(fā)表于 02-22 18:22 ?5次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 簡介

    RT-Thread文檔_RT-Thread SMP 介紹與移植

    RT-Thread文檔_RT-Thread SMP 介紹與移植
    發(fā)表于 02-22 18:31 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> SMP 介紹與移植

    RT-Thread文檔_UART 設(shè)備

    RT-Thread文檔_UART 設(shè)備
    發(fā)表于 02-22 18:32 ?2次下載
    <b class='flag-5'>RT-Thread</b>文檔_UART <b class='flag-5'>設(shè)備</b>

    RT-Thread文檔_CAN 設(shè)備

    RT-Thread文檔_CAN 設(shè)備
    發(fā)表于 02-22 18:34 ?0次下載
    <b class='flag-5'>RT-Thread</b>文檔_CAN <b class='flag-5'>設(shè)備</b>

    RT-Thread文檔_PWM 設(shè)備

    RT-Thread文檔_PWM 設(shè)備
    發(fā)表于 02-22 18:35 ?1次下載
    <b class='flag-5'>RT-Thread</b>文檔_PWM <b class='flag-5'>設(shè)備</b>

    RT-Thread文檔_SPI 設(shè)備

    RT-Thread文檔_SPI 設(shè)備
    發(fā)表于 02-22 18:36 ?2次下載
    <b class='flag-5'>RT-Thread</b>文檔_SPI <b class='flag-5'>設(shè)備</b>

    RT-Thread文檔_WATCHDOG 設(shè)備

    RT-Thread文檔_WATCHDOG 設(shè)備
    發(fā)表于 02-22 18:36 ?1次下載
    <b class='flag-5'>RT-Thread</b>文檔_WATCHDOG <b class='flag-5'>設(shè)備</b>

    RT-Thread文檔_SENSOR 設(shè)備

    RT-Thread文檔_SENSOR 設(shè)備
    發(fā)表于 02-22 18:37 ?0次下載
    <b class='flag-5'>RT-Thread</b>文檔_SENSOR <b class='flag-5'>設(shè)備</b>

    RT-Thread文檔_AUDIO 設(shè)備

    RT-Thread文檔_AUDIO 設(shè)備
    發(fā)表于 02-22 18:38 ?0次下載
    <b class='flag-5'>RT-Thread</b>文檔_AUDIO <b class='flag-5'>設(shè)備</b>

    RT-Thread文檔_Pulse Encoder 設(shè)備

    RT-Thread文檔_Pulse Encoder 設(shè)備
    發(fā)表于 02-22 18:39 ?1次下載
    <b class='flag-5'>RT-Thread</b>文檔_Pulse Encoder <b class='flag-5'>設(shè)備</b>

    淺析RT-Thread設(shè)備驅(qū)動(dòng)框架

    RT-Thread 設(shè)備框架屬于組件和服務(wù)層,是基于 RT-Thread 內(nèi)核之上的上層軟件。設(shè)備框架是針對某一類外設(shè),抽象出來的一套統(tǒng)一的操作方法及接入標(biāo)準(zhǔn),可以屏蔽硬件差異,為應(yīng)用
    的頭像 發(fā)表于 08-07 15:39 ?1734次閱讀