找回密码
 立即注册
楼主: Cos***

全局不关总中断的 RTOS,CosyOS视频教学, 送【USB转双串口,烧录器,仿真器】

 火... [复制链接]
  • TA的每日心情
    奋斗
    半小时前
  • 签到天数: 203 天

    [LV.7]常住居民III

    5

    主题

    648

    回帖

    2663

    积分

    荣誉版主

    积分
    2663
     楼主| 发表于 2023-11-27 12:46:43 | 显示全部楼层
    本帖最后由 CosyOS 于 2023-12-1 19:29 编辑

    CosyOS-II 最新版 V1.2.0-beta 发布!

    中断本地服务(只读访问)的问题,一直以来都是CosyOS的历史遗留问题,未能得到有效的解决。
    本次发布新版,就是为了更好的解决相关问题。
    CosyOS的中断本地服务主要包括:全局变量的只读访问、接收邮件、接收消息、接收飞信。
    对于中断中接收邮件、接收消息、接收飞信,本次未做调整,原有方案不变。
    本次升级就是要彻底解决全局变量的访问问题,给用户提供更多的选择。

    一个非原子访问的全局变量,在不关闭总中断的前提下,如何实现全局“成功的互斥访问”?CosyOS-II为您提供了解决方案。

    这里说成功的互斥访问,是为了区别采用信号量、互斥量等方式实现的互斥访问,强调其访问结果一定是成功的,不会失败。

    一、任务中访问
    对于任务中的访问,无论只读访问、只写访问、读写访问,只需在任务临界区中访问即可实现
    “成功的互斥访问”

    二、滴答中访问
    对于滴答中的访问,无论只读访问、只写访问、读写访问,直接访问即可实现
    “成功的互斥访问”

    三、中断中访问
    对于中断中的访问,针对只读访问、只写访问、读写访问,需做不同的处理。

    1、只读访问
    对于中断中的只读访问,用户需定义全局变量的副本,并按照指定方式来更新副本。
    读全局变量时,需调用 iWhichGVarToRead 来询问:应该读哪一个全局变量?返回0读正本,返回1读副本。

    即可实现“成功的互斥访问”

    2、只写访问
    对于中断中的只写访问,直接调用相应的API即可实现
    “成功的互斥访问”
    (1)写全局变   量:iWriteGVar(gv, lv)
    (2)写全局数   组:iWriteGAry(gp, lp, size)
    (3)写全局字符串:iWriteGStr(gs, ls)

    3、读写访问
    对于中断中的读写访问,有下述两种方式可供选择:
    (1)挂起服务调用iPendSVC(fp),fp为自定义的函数指针。
    (2)中断服务钩子void pendsv_hook(void)

    关于中断中的读写访问,要想说透还是不太容易的,这里先说一个结论:
    (1)在PendSV中,整个中断挂起服务的执行过程是不安全的,在这个过程中最好不要有全局变量的读访问。
         因为在这个过程中,有可能会出现临时性的写结果错误,但只要整个过程完成后,其结果便会复写为正确。
         这种临时性的写结果错误,仅可能发生在当一个中断连续两次进入间隔时间过短并调用了只写访问(局部写给全局)。
    (2)中断服务钩子是在整个中断挂起服务执行完成后被调用,可实现安全的读访问。

    具体应用:
    (1)一般情况下,全局变量的自运算,可采用挂起服务调用,因为该全局变量通常不会再在其它中断中执行只写访问。
    (2)多个全局变量的混合运算或读写,应采用中断服务钩子。
    (3)可尽量采用中断服务钩子,以确保实现安全访问。



    /*
    * CosyOS-II 最新版 V1.2.0 全局变量访问相关API
    */

    /* 更新全局变量副本 */
    uUpdateCopy_GVar(code)
    tUpdateCopy_GVar(code)

    /* 读哪一个全局变量?(返回0读正本,返回1读副本)*/
    iWhichGVarToRead

    /* 写全局变量 */
    iWriteGVar(gv, lv)

    /* 写全局数组 */
    iWriteGAry(gp, lp, size)

    /* 写全局字符串 */
    iWriteGStr(gs, ls)

    /* 挂起服务调用 */
    iPendSVC(fp)



    /*
    * 应用示例
    * 有三个非原子访问的全局变量,均会在任务、滴答、中断中执行只读访问、只写访问、自运算。
    */

    /* 定义全局变量 */
    u32  xdata g_var = 2147483647;
    char xdata g_ary[32];
    char xdata g_str[32];

    /* 定义全局变量的副本 for 中断中的只读访问 */
    u32  xdata g_var_copy = 2147483647;
    char xdata g_ary_copy[32];
    char xdata g_str_copy[32];



    /*
    * 方案一:智能应用
    * 在全局变量钩子中更新所有副本。
    */

    任务中:
    {
            u32  l_var;
            char l_ary[32];
            char l_str[32];
            uEnterCritical; // 进入任务临界区
            
            /* 读全局变量 */
            l_var = g_var;
            memcpy(l_ary, g_ary, 32);
            strcpy(l_str, g_str);
            
            /* 写全局变量 */
            g_var = l_var;
            memcpy(g_ary, l_ary, 32);
            strcpy(g_str, l_str);
            
            /* 全局变量自运算 */
            g_var++;
            
            uExitCritical; // 退出任务临界区
            uEndTasking;
    }

    滴答中:
    {
            u32  l_var;
            char l_ary[32];
            char l_str[32];
            
            /* 读全局变量 */
            l_var = g_var;
            memcpy(l_ary, g_ary, 32);
            strcpy(l_str, g_str);
            
            /* 写全局变量 */
            g_var = l_var;
            memcpy(g_ary, l_ary, 32);
            strcpy(g_str, l_str);

            /* 全局变量自运算 */
            g_var++;
    }

    static void g_var_inc(void) MCUCFG_USING
    {
            g_var++;
    }

    中断中:
    {
            u32  l_var;
            char l_ary[32];
            char l_str[32];
            
            /* 读全局变量 */
            l_var = !iWhichGVarToRead ? g_var : g_var_copy;
            memcpy(l_ary, !iWhichGVarToRead ? g_ary : g_ary_copy, 32);
            strcpy(l_str, !iWhichGVarToRead ? g_str : g_str_copy);
            
            /* 写全局变量 */
            iWriteGVar(g_var, l_var);
            iWriteGAry(g_ary, l_ary, 32);
            iWriteGStr(g_str, l_str);
            
            /* 全局变量自运算 */
            iPendSVC(g_var_inc);
    }

    /* 全局变量钩子 */// 更新所有副本
    void gvar_hook(void) MCUCFG_USING
    {
            g_var_copy = g_var;
            memcpy(g_ary_copy, g_ary, 32);
            strcpy(g_str_copy, g_str);
    }



    /*
    * 方案二:立即更新 + 针对更新
    * 在任务和滴答中写全局变量以后,立即更新副本;
    * 针对中断中有可能会写全局变量,在全局变量钩子中做判断并针对更新副本。
    */

    uCreateBin(g_ary_bin) = false; // for针对更新副本
    uCreateBin(g_str_bin) = false; // for针对更新副本

    任务中:
    {
            u32  l_var;
            char l_ary[32];
            char l_str[32];
            uEnterCritical; // 进入任务临界区
            
            /* 读全局变量 */
            l_var = g_var;
            memcpy(l_ary, g_ary, 32);
            strcpy(l_str, g_str);
            
            /* 写全局变量 */
            g_var = l_var;
            uUpdateCopy_GVar(g_var_copy = g_var); // 立即更新副本
            
            memcpy(g_ary, l_ary, 32);
            uUpdateCopy_GVar(memcpy(g_ary_copy, g_ary, 32)); // 立即更新副本
            
            strcpy(g_str, l_str);
            uUpdateCopy_GVar(strcpy(g_str_copy, g_str)); // 立即更新副本
            
            /* 全局变量自运算 */
            g_var++;
            uUpdateCopy_GVar(g_var_copy = g_var); // 立即更新副本
            
            uExitCritical; // 退出任务临界区
            uEndTasking;
    }

    滴答中:
    {
            u32  l_var;
            char l_ary[32];
            char l_str[32];
            
            /* 读全局变量 */
            l_var = g_var;
            memcpy(l_ary, g_ary, 32);
            strcpy(l_str, g_str);
            
            /* 写全局变量 */
            g_var = l_var;
            tUpdateCopy_GVar(g_var_copy = g_var); // 立即更新副本
            
            memcpy(g_ary, l_ary, 32);
            tUpdateCopy_GVar(memcpy(g_ary_copy, g_ary, 32)); // 立即更新副本
            
            strcpy(g_str, l_str);
            tUpdateCopy_GVar(strcpy(g_str_copy, g_str)); // 立即更新副本
            
            /* 全局变量自运算 */
            g_var++;
            tUpdateCopy_GVar(g_var_copy = g_var); // 立即更新副本
    }

    static void g_var_inc(void) MCUCFG_USING
    {
            g_var++;
    }

    中断中:
    {
            u32  l_var;
            char l_ary[32];
            char l_str[32];
            
            /* 读全局变量 */
            l_var = !iWhichGVarToRead ? g_var : g_var_copy;
            memcpy(l_ary, !iWhichGVarToRead ? g_ary : g_ary_copy, 32);
            strcpy(l_str, !iWhichGVarToRead ? g_str : g_str_copy);
            
            /* 写全局变量 */
            iWriteGVar(g_var, l_var);
            
            iWriteGAry(g_ary, l_ary, 32);
            iGiveBin(g_ary_bin); // for针对更新副本
            
            iWriteGStr(g_str, l_str);
            iGiveBin(g_str_bin); // for针对更新副本
            
            /* 全局变量自运算 */
            iPendSVC(g_var_inc);
    }

    /* 全局变量钩子 */// 针对更新副本
    void gvar_hook(void) MCUCFG_USING
    {
            g_var_copy = g_var;
            if(g_ary_bin){
                    g_ary_bin = false;
                    memcpy(g_ary_copy, g_ary, 32);
            }
            if(g_str_bin){
                    g_str_bin = false;
                    strcpy(g_str_copy, g_str);
            }
    }



    中断中的只读访问

    1、要慎重选择上述的副本方式,因为副本会占用更多的内存,更新副本会占用额外的时间,影响系统的实时性。
         建议只有少量的、小型的全局变量或数组采用此种方式。
    2、其它的全局变量,尤其是大型的数组,应尽量实现逻辑时序控制,使其不会重入;
         或采用二值信号量等方式实现互斥访问。
    3、如果采用二值信号量、全局临界区等方式来实现互斥访问,那么全局(任务、滴答、中断)都要采用相同的方式来访问同一个全局变量。
    4、如果一个非原子访问的全局变量不会在中断中读取,那么事情将变得异常简单。即不用定义副本,也不用更新副本,其它各处访问如同示例中访问即可。





    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    566

    主题

    9970

    回帖

    1万

    积分

    管理员

    积分
    14467
    发表于 2023-11-27 17:21:16 | 显示全部楼层
    帮程序放一楼,另外没看到新程序在哪 ?
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    半小时前
  • 签到天数: 203 天

    [LV.7]常住居民III

    5

    主题

    648

    回帖

    2663

    积分

    荣誉版主

    积分
    2663
     楼主| 发表于 2023-11-28 17:00:37 | 显示全部楼层
    CosyOS 发表于 2023-11-27 12:46
    CosyOS-II 最新版 V1.2.0-beta 发布!

    中断本地服务(只读访问)的问题,一直以来都是CosyOS的历史遗留问 ...

    原有描述中的“可重入访问”是不妥的,现调整为“成功的互斥访问”
    之所以会出现这个问题,是为了区别一般的互斥访问,强调CosyOS所采用的互斥访问机制,其访问结果一定是成功的、不会失败。

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    半小时前
  • 签到天数: 203 天

    [LV.7]常住居民III

    5

    主题

    648

    回帖

    2663

    积分

    荣誉版主

    积分
    2663
     楼主| 发表于 2023-11-28 19:46:15 | 显示全部楼层
    本帖最后由 CosyOS 于 2023-11-30 11:35 编辑

    CosyOS-II  关于全局变量访问的补充说明

    由于访问分类的复杂性,可分为只读访问、只写访问、读写访问(自运算);又分为赋值、memcpy、strcpy;又要分为三个不同的调用位置(任务、滴答、中断);
    所以,访问过程的代码要尽量由用户自己完成,系统尽可能不要提供相关的服务,否则将会导致简单问题复杂化,降低易用性。
    当前,CosyOS-II 只为中断提供了少量的、必要的服务用于全局变量访问,任务、滴答中都没有提供,由用户自己选择合适的访问方式。

    CosyOS-II 当前所提供的全局变量的访问方法,全局变量副本的定义与更新都交由用户自行处理,看似有些麻烦,实则已经是最简单、最易用的方法了。


    智能应用立即更新 + 针对更新 的区别
    智能应用,具有更好的易用性,用户操作起来更为简单。缺点是全局变量副本的更新会有延迟,最多延迟一个滴答周期;漫无目的的更新副本会多花费一些时间。
    立即更新 + 针对更新,可实现全局变量副本的及时更新,更新所用的时间会更少,但易用性差。






    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    1 小时前
  • 签到天数: 164 天

    [LV.7]常住居民III

    2

    主题

    89

    回帖

    688

    积分

    高级会员

    积分
    688
    发表于 2023-12-1 08:47:06 来自手机 | 显示全部楼层
    看不懂,但是很震撼
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    1 小时前
  • 签到天数: 164 天

    [LV.7]常住居民III

    2

    主题

    89

    回帖

    688

    积分

    高级会员

    积分
    688
    发表于 2023-12-1 16:52:14 来自手机 | 显示全部楼层
    选择与判断 发表于 2023-12-1 08:47
    看不懂,但是很震撼

    嗯,等我摸清了一点门道就去试试。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    半小时前
  • 签到天数: 203 天

    [LV.7]常住居民III

    5

    主题

    648

    回帖

    2663

    积分

    荣誉版主

    积分
    2663
     楼主| 发表于 2023-12-4 02:21:46 | 显示全部楼层
    本帖最后由 CosyOS 于 2023-12-4 03:32 编辑

    CosyOS-II 最新版测试程序发布(CosyOS-II 内核版本 V1.2.0-beta)

    1、基于 FreeRTOS-STC32G-CORE-V1.0.2-Library-DemoCode-20220817 修改的,将FreeRTOS替换为CosyOS-II的示例代码;
    2、CosyOS-II 专业版测试程序 V1.0.1。

       (1)专业版测试程序新增  任务临界区测试  和  全局变量测试
       (2)为了方便 全局变量 测试,专业版测试程序默认已启用 滴答钩子全局变量钩子
       (3)专业版测试程序 for STC32G,已配置为 Generate reentrant functions + “REMOVEUNUSED”,如不改配置方案 则无法做“私信”测试。

    请顶楼下载!







    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-23 16:29
  • 签到天数: 85 天

    [LV.6]常住居民II

    8

    主题

    101

    回帖

    646

    积分

    高级会员

    积分
    646
    发表于 2023-12-4 11:20:40 | 显示全部楼层
    建议厂家还是不要放弃皮带封装,有些产品没有pid封装,有些让人恼火,因为打样的成本远远高于直接购买pid封装的mcu,还有其二,当产品做到超过100mhz的时候,也不要放弃pid封装,至少我喜欢,别人我不知道了,因为在程序运行之后,从io口出来的数据流并不是很高,
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 小时前
  • 签到天数: 160 天

    [LV.7]常住居民III

    4

    主题

    239

    回帖

    1008

    积分

    金牌会员

    积分
    1008
    发表于 2023-12-7 00:51:23 | 显示全部楼层
    等我的积分够了也兑换快板子试试
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    20

    主题

    587

    回帖

    1305

    积分

    荣誉版主

    积分
    1305
    发表于 2023-12-12 09:47:24 | 显示全部楼层
    Hello, CosyOS, 好久没说过话了呀, 最近有什么新突破没

    点评

    你最近忙些什么?  发表于 2023-12-12 13:22
    最近我这边没有任何新动作,CosyOS的各项基本功能和技术手段均已定型。 当前正在写API使用说明书。  详情 回复 发表于 2023-12-12 12:50
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-6-16 14:25 , Processed in 0.076398 second(s), 69 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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