硬汉嵌入式论坛

 找回密码
 立即注册
查看: 16360|回复: 28
收起左侧

[ThreadX全家桶] Threadx全家桶番外篇之STM32cubeIDE携手Threadx + ModuleX动态应用加载 C位出道

  [复制链接]

7

主题

74

回帖

100

积分

初级会员

积分
100
发表于 2021-3-25 00:03:04 | 显示全部楼层 |阅读模式
本帖最后由 feelingcode 于 2021-7-7 00:37 编辑

硬汉的ThreadX综合例程,ThreadX内核,FileX,NetXDUO,USBX,GUIX悉数到场,MDK AC5,MDK AC6,IAR和GCC四个版本也元神归位。是不是还差点什么,没错那就来一个STM32cubeIDE + ModuleX动态应用加载爽一下。
en....
ThreadX内核,FileX,NetXDUO,USBX,GUIX,ModuleX悉数到场,MDK AC5,MDK AC6,IAR、GCC(Embedded Studio)和 GCC (STM32cubeIDE)五个版本元神归位也不错。

开发环境:
操作系统 WINDOW7
开发板  安富莱V7开发板
开发工具 STM32cubeIDE、STM32CubeProgrammer、gcc-arm-none-eabi

STM32cubeIDE的gcc-arm-none-eabi加入系统环境变量:参考路径:C:\STM32CubeIDE_1.4.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_1.5.0.202011040924\tools\bin

工程文件:
threadx_projec_1.0.zip (2.7 MB, 下载次数: 117)

想像用手机APP一样安装程序? 那它来了。。。。" />
第一步:

工程介绍

工程介绍

第二步:
360截图164101117011899.png
第三步:
360截图16200706104123116.png

第四步:
路径:threadx_projec_1.0\threadx_module\module1
文件:sample_threadx_module.c 里的函数thread_2_entry线程负责++计数
void    thread_2_entry(ULONG thread_input)
{

ULONG   received_message;
UINT    status;

    /* This thread retrieves messages placed on the queue by thread 1.  */
    while(1)
    {
        /* Test memory handler.  */
        *(ULONG *)0x20010000 = thread_2_counter++;

        tx_thread_sleep(1000);

        /* Retrieve a message from the queue.  */
        status = tx_queue_receive(queue_0, &received_message, TX_WAIT_FOREVER);

        /* Check completion status and make sure the message is what we
           expected.  */
        if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
            break;

        /* Otherwise, all is okay.  Increment the received message count.  */
        thread_2_messages_received++;
    }
}

串口工具打印结果:
982HP[`90NB1W${YJVBVPBF.png



到此,系统完成动态应用加载并且成功运行!!!

上面说明没搞懂或者感兴趣的可以看一下官方文档和官方例程了解一下,

官方文档:https://docs.microsoft.com/en-us/azure/rtos/threadx-modules/chapter1
官方例程:https://github.com/azure-rtos/threadx/tree/master/ports_module/cortex-m7/gnu








360截图16280715697188.png

评分

参与人数 2金币 +120 收起 理由
lhaoyue + 20 很给力!
eric2013 + 100 很给力!

查看全部评分

回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-3-25 00:07:30 | 显示全部楼层
本帖最后由 feelingcode 于 2021-3-25 22:37 编辑

可玩性还是很高的,还在摸索中。。。
回复

使用道具 举报

3

主题

163

回帖

172

积分

初级会员

积分
172
发表于 2021-3-25 08:49:45 | 显示全部楼层
比较感兴趣,期待楼主后续文章。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
发表于 2021-3-25 09:47:33 | 显示全部楼层
谢谢楼主分享,有个工程就足够了。
回复

使用道具 举报

56

主题

904

回帖

1072

积分

至尊会员

积分
1072
发表于 2021-3-25 10:54:59 | 显示全部楼层
这个好,一直以来都想把所有的集成到cubemx里面。太方便了。
回复

使用道具 举报

6

主题

19

回帖

37

积分

新手上路

积分
37
发表于 2021-3-25 14:00:18 | 显示全部楼层
能介绍一下这个工程怎么用吗?
回复

使用道具 举报

73

主题

1192

回帖

1411

积分

至尊会员

积分
1411
发表于 2021-3-25 21:22:31 | 显示全部楼层
牛逼啊
回复

使用道具 举报

6

主题

636

回帖

654

积分

金牌会员

积分
654
QQ
发表于 2021-3-27 15:15:16 | 显示全部楼层
没看懂怎么使用,
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-3-30 22:54:05 | 显示全部楼层
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-7-7 08:55:17 | 显示全部楼层
动态应用加载成功运行了,工程已更新。。。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
发表于 2021-7-8 00:15:36 | 显示全部楼层
置cool
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-7-8 08:58:26 | 显示全部楼层

路径:threadx_projec_1.0\threadx_module\module1\sample_threadx_module.c
如果在这个文件给全局变量默认值,应用就运行不了,麻烦硬汉帮忙看一原因,工程都是基于V7开发板的。
例如:
ULONG           thread_0_counter = 0x55AA55AA;
回复

使用道具 举报

3

主题

163

回帖

172

积分

初级会员

积分
172
发表于 2021-7-8 09:11:22 | 显示全部楼层
楼主厉害,终于突破了,参考楼主的工程研究下。
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-7-8 09:23:09 | 显示全部楼层
jowo_pBuGF 发表于 2021-7-8 09:11
楼主厉害,终于突破了,参考楼主的工程研究下。

终于突破了,分享给大家一起研究。
回复

使用道具 举报

3

主题

1222

回帖

1231

积分

至尊会员

积分
1231
发表于 2021-7-8 12:44:19 | 显示全部楼层
这种玩法,在Keil MDK下可以不 ?
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-7-8 14:08:12 | 显示全部楼层
morning_enr6U 发表于 2021-7-8 12:44
这种玩法,在Keil MDK下可以不 ?

可以的,参考:https://github.com/azure-rtos/th ... odule/cortex_m7/ac5
回复

使用道具 举报

6

主题

42

回帖

60

积分

初级会员

积分
60
发表于 2021-7-8 17:15:20 | 显示全部楼层
厉害了,threadx还真能这样玩儿
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-7-8 23:05:19 | 显示全部楼层
wozaihuayu 发表于 2021-7-8 17:15
厉害了,threadx还真能这样玩儿

就这个好玩
回复

使用道具 举报

2

主题

21

回帖

27

积分

新手上路

积分
27
发表于 2021-7-14 18:13:13 | 显示全部楼层
实测,对于有cache的芯片,load之后直接start的方式有坑。比如用内存拷贝把模块加载到一片内存,数据(数据+代码)采用回写可能有部分驻留在Dcache里,而运行模块时会从Icache或内存里取指令,导致模块发生错误。所以正确流程应该在load 之后 ,clean 模块所在位置的Dcache,inv模块所在位置的Icache,然后才能执行txm_module_manager_start
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-7-15 10:39:28 | 显示全部楼层
本帖最后由 feelingcode 于 2021-7-15 10:56 编辑
luguan1997 发表于 2021-7-14 18:13
实测,对于有cache的芯片,load之后直接start的方式有坑。比如用内存拷贝把模块加载到一片内存,数据(数据 ...
对于cache的坑,工程上需要增加红色部分代码。

void    module_manager_entry(ULONG thread_input)
{

    /* Initialize the module manager.   */
    txm_module_manager_initialize((VOID *) module_ram, 32768);

    txm_module_manager_object_pool_create(object_memory, sizeof(object_memory));

    /* Register a fault handler.  */
    txm_module_manager_memory_fault_notify(module_fault_handler);
   
    /* Load the module that is already there, in this example it is placed there by the multiple image download.  */
    txm_module_manager_memory_load(&my_module, "my module", (VOID *) 0x08100000);
   
    /* Enable 128 byte read/write shared memory region at 0x20010000.  */
    txm_module_manager_external_memory_enable(&my_module, (void *) 0x20010000, 128, TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE);
        
    SCB_CleanInvalidateDCache_by_Addr((uint32_t*)object_memory,16384);
    SCB_CleanInvalidateDCache_by_Addr((uint32_t*)module_ram,32768);
    SCB_InvalidateICache_by_Addr((uint32_t*)module_ram,32768);

        
    /* Start the module.  */
    txm_module_manager_start(&my_module);

   
    /* Now just spin...  */
    while(1)
    {
            printf("module manager run...\r\n");
            printf("my app module run count %ld\r\n",*(ULONG *)0x20010000);
            tx_thread_sleep(1000);
    }
}
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-7-15 11:26:59 | 显示全部楼层
luguan1997 发表于 2021-7-14 18:13
实测,对于有cache的芯片,load之后直接start的方式有坑。比如用内存拷贝把模块加载到一片内存,数据(数据 ...

实际还有挺多坑,这方面资料太少了

例如不能在模块文件sample_threadx_module.c里定义全局变量默认值:

ULONG           thread_0_counter = 0x55AA55AA;

这样程序直接就进_txm_module_manager_memory_fault_handler,线程被 _tx_thread_terminate()函数终止。
回复

使用道具 举报

2

主题

21

回帖

27

积分

新手上路

积分
27
发表于 2021-7-20 19:46:16 | 显示全部楼层
本帖最后由 luguan1997 于 2021-7-21 09:51 编辑
feelingcode 发表于 2021-7-15 11:26
实际还有挺多坑,这方面资料太少了

例如不能在模块文件sample_threadx_module.c里定义全局变量默认值 ...

默认值的问题是它没把data段copy过去,把模块的ld文件 __code_size__设成  __code_size__ = __rodata_end__ - __FLASH_segment_start__ + SIZEOF(.data);(可能有更好的改法);至于是默认值导致module终止我没遇到,可能平台不同,我gcc 跑的别的芯片
回复

使用道具 举报

2

主题

21

回帖

27

积分

新手上路

积分
27
发表于 2021-7-21 09:52:20 | 显示全部楼层
__code_size__ = __rodata_end__ - __FLASH_segment_start__ + SIZEOF(.data);
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-7-21 19:46:03 | 显示全部楼层
luguan1997 发表于 2021-7-20 19:46
默认值的问题是它没把data段copy过去,把模块的ld文件 __code_size__设成  __code_size__ = __rodata_end ...

默认值问题已经在github上得到官方确认,等后面更新修正。
回复

使用道具 举报

2

主题

21

回帖

27

积分

新手上路

积分
27
发表于 2021-7-21 21:40:57 | 显示全部楼层
我之前移植还遇到一个问题是,开启了宏TX_ENABLE_STACK_CHECKING,在调用 开启mmu/mpu保护的模块时,会检测到栈错误(通过检查栈区的位置和标记为0xEF的内存是否被踩),改大栈尺寸也没用。调试发现它给模块线程分配了两个栈区,当用户态进入内核态后,栈区会切换,而这个新栈区似乎配置有问题,我把txm_module_manager_thread_create.c 的335行
  1. thread_ptr -> tx_thread_module_kernel_stack_end = (VOID *) (((ALIGN_TYPE)(thread_ptr -> tx_thread_module_kernel_stack_start) + TXM_MODULE_KERNEL_STACK_SIZE) & ~0x07);
复制代码

改成
  1. thread_ptr -> tx_thread_module_kernel_stack_end = (VOID *) (((ALIGN_TYPE)(thread_ptr -> tx_thread_module_kernel_stack_start) + TXM_MODULE_KERNEL_STACK_SIZE - 8) & ~0x07);
复制代码
就可以了
回复

使用道具 举报

0

主题

8

回帖

8

积分

新手上路

积分
8
发表于 2021-10-9 20:27:57 | 显示全部楼层
请问高手,在模块里面怎么访问硬件设备?
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2021-10-18 09:07:49 | 显示全部楼层
likeping 发表于 2021-10-9 20:27
请问高手,在模块里面怎么访问硬件设备?

不能直接用,需要再做一层API给模块调用
回复

使用道具 举报

3

主题

11

回帖

20

积分

新手上路

积分
20
发表于 2023-1-12 15:10:20 | 显示全部楼层
有个疑问,模块编译的时候链接到了指定地址,那么运行时是不是必须加载到目标地址?
包括程序地址和变量地址。
回复

使用道具 举报

7

主题

74

回帖

100

积分

初级会员

积分
100
 楼主| 发表于 2023-2-9 11:30:15 | 显示全部楼层
opensix 发表于 2023-1-12 15:10
有个疑问,模块编译的时候链接到了指定地址,那么运行时是不是必须加载到目标地址?
包括程序地址和变量地 ...

在编译时候选择位置无关就行
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-26 15:22 , Processed in 0.549061 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表