发新帖本帖赏金 3.00元(功能说明)我要提问
返回列表
打印

VSF然并卵之二,另类模块化

[复制链接]
2425|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Simon21ic|  楼主 | 2015-8-23 12:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Simon21ic 于 2015-8-23 12:20 编辑

然并卵系列之一是动态加载,cortexM上,实现对应用程序的动态加载,应用程序开发的时候,可以选择cortexM0,而不用选择特定的芯片。
对了,然并卵系列,只讲一些可以玩玩,但是没太大用处的技术。


能够实现这个后,可以继续开大脑洞,系统的各个模块都适用动态加载的方式。
系统只需要具备VSF的核心构架,多任务和事件驱动,通用接口的处理器驱动,bootloader。
然后,系统以外的flash的第一块用于配置flash中的哪些位置有需要载入的模块。

系统启动后,就一一载入各个模块。模块间使用接口来通信。

这么实现的模块化,就不仅仅是C代码的一个模块,模块已经被当作一个独立工程编译了。

想到之前IAR发律师函,为啥不把模块分好,每个模块小于32K,IAR不就是免费的了?

上一个简单的模块代码吧。

struct vsfapp_t
{
        struct vsf_module_t module;
        struct led_ifs_t ifs;
};

static vsf_err_t led_init(struct led_t *led)
{
        struct led_hw_t const *hwled = led->hw;
       
        led->on = false;
        core_interfaces.gpio.init(hwled->lport);
        core_interfaces.gpio.clear(hwled->lport, 1 << hwled->lpin);
        core_interfaces.gpio.config_pin(hwled->lport, hwled->lpin,
                                                                        core_interfaces.gpio.constants.OUTPP);
        core_interfaces.gpio.init(hwled->hport);
        core_interfaces.gpio.clear(hwled->hport, 1 << hwled->hpin);
        core_interfaces.gpio.config_pin(hwled->hport, hwled->hpin,
                                                                        core_interfaces.gpio.constants.OUTPP);
        return VSFERR_NONE;
}

static vsf_err_t led_on(struct led_t *led)
{
        return core_interfaces.gpio.set(led->hw->hport, 1 << led->hw->hpin);
}

static vsf_err_t led_off(struct led_t *led)
{
        return core_interfaces.gpio.clear(led->hw->hport, 1 << led->hw->hpin);
}

static bool led_is_on(struct led_t *led)
{
        return led->on;
}

vsf_err_t __iar_program_start(struct app_hwcfg_t const *hwcfg)
{
        struct vsfapp_t *app;
       
        // check board and api version
        if (strcmp(hwcfg->board, APP_BOARD_NAME) ||
                (vsf_api_ver != VSF_API_VERSION))
        {
                return VSFERR_NOT_SUPPORT;
        }
       
        app = vsf_bufmgr_malloc(sizeof(struct vsfapp_t));
        if (NULL == app)
        {
                return VSFERR_NOT_ENOUGH_RESOURCES;
        }
       
        memset(app, 0, sizeof(*app));
       
        app->ifs.init = led_init;
        app->ifs.on = led_on;
        app->ifs.off = led_off;
        app->ifs.is_on = led_is_on;
        app->module.ifs = &app->ifs;
        app->module.name = "led";
        return vsf_module_load(&app->module);
}
这里,程序入口不是main,而是__iar_program_start,编译器不会加入C的一些初始化代码,也不会加入芯片的中断向量。当然,ropi是必须的。
__iar_program_start传入一个硬件配置文件,程序先检测硬件配置文件是否是自己可以运行的板子,并且检查系统API版本是否和自己用的一致。
之后就动态分配自己需要的内存,并且初始化,注册自己的模块(模块中,有接口的指针)。

其他模块或者应用可以查找这个模块,得到接口,然后调用模块中的功能。其他模块如果需要led模块,但是led模块还没有注册的话,可以使用模块的回调接口:
 // get led_module
        led_mod = vsf_module_get("led");
        if (NULL == led_mod)
        {
                app->app_mod.name = "app";
                app->app_mod.callback.on_load = app_on_load;
                return VSFERR_NONE;
        }
        app_on_load(&app->app_mod, led_mod);
        return VSFERR_NONE;
}
这里,没有得到led模块,就注册app模块,设置on_load接口,之后系统载入模块的时候,都会调用on_load。这样也就用简单的方式,解决模块依赖性问题。

另外,这里,模块调用的系统函数,一直想不到好的方法解决,就只是把接口放在中断向量后,0x200的位置,希望大部分cortexM这里都可以用吧。

和动态加载一样,由于CortexM并不具备MMU,这种设计方式,并没有什么用。
可能如果程序规模大于32K,可以用这种方式分割成各个小模块,让IAR永久免费吧。

打赏榜单

21ic小喇叭 打赏了 3.00 元 2015-08-27

相关帖子

沙发
Simon21ic|  楼主 | 2015-8-23 17:55 | 只看该作者
本帖最后由 Simon21ic 于 2015-8-23 17:59 编辑
yyy71cj 发表于 2015-8-23 17:05
嗯,看见“嵌入式”的身影了……

本来就是嵌入式系统,32位处理器上跑的,这里可以讨论的吧
现在32位ARM嵌入式系统很多人玩,你不玩的吗?

使用特权

评论回复
板凳
Simon21ic|  楼主 | 2015-8-23 18:16 | 只看该作者
有一个讨论很有意思,嵌入式系统和一般MCU系统,如何定义区别?
我大学毕业的时候,就都是玩ARM7的了,虽然做过AVR的技术支持,不过自己的产品很少用8位处理器,因为普及的8位处理器,**相对容易很多。
是不是32位就算嵌入式了?

使用特权

评论回复
地板
Simon21ic|  楼主 | 2015-8-24 10:24 | 只看该作者
本帖最后由 Simon21ic 于 2015-8-24 10:34 编辑
yyy71cj 发表于 2015-8-24 07:01
嵌入式,按我的理解,应该是单片机中嵌入了微操作系统,而我们的程序,又是嵌入在微操作系统中的一段自定 ...

有用到操作系统的就是嵌入式吗?不是按照处理器性能区分的?
在你的书里,完全也可以用面向对象的方式,定义出一些线程的类,主循环里轮询这些类的各个实例。应用中的线程,都继承自同一个线程类。当然,IPC机制也可以使用类。那算不算操作系统?算不算嵌入式?

另外我倒是觉得bootloader是看开发需求是否要求IAP,并不是必须的。

使用特权

评论回复
5
keer_zu| | 2015-8-24 10:28 | 只看该作者
yyy71cj 发表于 2015-8-24 07:01
嵌入式,按我的理解,应该是单片机中嵌入了微操作系统,而我们的程序,又是嵌入在微操作系统中的一段自定 ...

首先嵌入式系统不是这样定义的。

使用特权

评论回复
6
walnutcy| | 2015-8-24 23:04 | 只看该作者
楼主,规避32K很好处理的,FLASH模块化也是可行的

使用特权

评论回复
7
Simon21ic|  楼主 | 2015-8-25 00:34 | 只看该作者
walnutcy 发表于 2015-8-24 23:04
楼主,规避32K很好处理的,FLASH模块化也是可行的

这个不是为了规避32K,flash模块化是很容易的
我说的这个是基于动态载入的,这个模块可以在U盘里,通过usb host接口,载入到内存里运行
所以这个叫然并卵,对于cirtexM,这个没什么用,玩而已

使用特权

评论回复
8
keer_zu| | 2015-8-25 09:28 | 只看该作者
Simon21ic 发表于 2015-8-25 00:34
这个不是为了规避32K,flash模块化是很容易的
我说的这个是基于动态载入的,这个模块可以在U盘里,通过us ...

是不是对实现在线/在系统升级有用?我不太懂。

使用特权

评论回复
9
Simon21ic|  楼主 | 2015-8-25 10:00 | 只看该作者
keer_zu 发表于 2015-8-25 09:28
是不是对实现在线/在系统升级有用?我不太懂。

不是,这个就类似linux上,运行U盘里的elf一样,不过elf需要修改偏移的,我使用了ropi,地址无关代码+动态分配

使用特权

评论回复
10
逍遥派掌门| | 2015-9-3 01:59 | 只看该作者
个人认为,凡是内含代码控制的系统都可称为嵌入式,无论8位,32位。

使用特权

评论回复
11
Simon21ic|  楼主 | 2015-9-3 10:24 | 只看该作者
逍遥派掌门 发表于 2015-9-3 01:59
个人认为,凡是内含代码控制的系统都可称为嵌入式,无论8位,32位。

代码控制器是指可以代码的执行单元吗?PC算不算?

使用特权

评论回复
12
菜鸟同学| | 2015-9-7 13:18 | 只看该作者
为什么喜欢把MCU底层的都是封装了,这个工作量是不是太大了?

使用特权

评论回复
13
Simon21ic|  楼主 | 2015-9-7 13:39 | 只看该作者
菜鸟同学 发表于 2015-9-7 13:18
为什么喜欢把MCU底层的都是封装了,这个工作量是不是太大了?

是啊,工作量很大,不推荐使用,我们也只是玩玩而已

使用特权

评论回复
14
逍遥派掌门| | 2015-9-7 22:16 | 只看该作者
Simon21ic 发表于 2015-9-3 10:24
代码控制器是指可以代码的执行单元吗?PC算不算?

PC当然不算了 ,个头太大,嵌入不了。

使用特权

评论回复
发新帖 本帖赏金 3.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:www.versaloon.com --- under construction

266

主题

2597

帖子

104

粉丝