![7faf988957b49d9a1c059da11d1cdc1b.gif](https://i-blog.csdnimg.cn/blog_migrate/c3495eaf8787cccae9a229add493440f.gif)
![dfd898145b83d35fd9917f399fa29645.gif](https://i-blog.csdnimg.cn/blog_migrate/566483ecaed3db274fe5e3c9cb8f04f6.gif)
![bff3a7682448e26173351f456c82a1f9.gif](https://i-blog.csdnimg.cn/blog_migrate/1502bf72f6dedda1f33d7908aa6d1818.gif)
1
AUTOSAR(存储抽象)
1NvBlockSwComponents
注:以下AUTOSAR相关内容转载至CSDN博主「雪云飞星」 。大家AUTOSAR感兴趣可以访问原文。链接如下:
https://blog.csdn.net/xyfx_fhw/article/details/97122915
1、AutoSAR 4.x的优化
NvBlockSwComponents是S/R接口来做NVRAM的管理的,具有以下特点:
①可以将多个RAM变量聚合到一个NVRAM Block中
②对于NVRAM Blocks,支持扇入(Fan-in,可以理解为将多个SWC的数据导入到一个RAM Block中)和扇出(Fan-out,可以理解为将一个RAM Block中的数据导出到多个SWC的数据中)
③可以通过RTE对S/R的管理来防止并发访问的发生
④NvBlockSwComponents是可选的,没有需求可以不使用
2、架构
NvBlockDescriptor:主要作用是规定RAM Block的区域划分,也可以做NvBlock的Service Needs功能等,下一节课会讲解它的详细用法
NvBlockSwComponents:该SWC的代码一般来说是自动生成的,它会根据配置自动负责和NvM进行对接,来完成读写操作。还可以定义一些Service函数供NvM使用,比如当写入数据完成后,可以调用Rte_NvMNotifyJobFinished来处理写入完成的一些事
Fan-in:图中将两个Application的SWC的数据存入了一个RAM Block中
Fan-out:图中将一个RAM Block中的某个数据给到了多个SWC里
Fan-in/out:即Fan-in和Fan-out的功能都有
3、控制流
控制流是和NvBlockSwComponents的Runnable有关,因为Runnable才是控制的根本,NvBlockSwComponents中Runnable的触发只有三种条件:
• 定时周期触发
• Nv数据接收触发
• C/S接口调用触发
举例说明有:
①从Application SWC写一个数进入NV里,通过Nv数据接收触发的方式:
首先Application SWC通过Nv Port将要写入的数据传入NvBlockDescriptor设计好的RAM Block中(“3、架构” 那张图做的工作);然后由于这个Nv Port的写入操作,触发了WriteRunnable,该Runnable里会调用和NvM的C/S接口;最后由NvM_WriteBlock这个C/S接口去调用NvM中的写入函数,由NvM管理并写入数据
②从Application SWC写一个数进入NV里,通过C/S接口调用触发的方式:
首先也是Application SWC通过Nv Port将要写入的数据传入NvBlockDescriptor设计好的RAM Block中;然后Application SWC利用C/S接口调用NvBlockSwComponents的Service Runnable;再由该Runnable调用NvM里的NvM_WriteBlock这个C/S接口去调用NvM中的写入函数,由NvM管理并写入数据
③从Application SWC写一个数进入NV里,通过定时触发的方式:
也和上面类似,唯一的区别在于调用Runnable的方式变成了定时触发
二、 Nv Port
之前我们讲过了Port分为S/R和C/S Port,但其实还有几种特殊的Port,包括我们在模式管理中讲到的Mode Port,然后就是标定中用到的Calibration Port,还有就是我们在Nv中要使用到的Nv Port。它们的图标如下,从图标中来看,它们都是属于S/R接口的一种
三、NV Block SWC
我们建立NvBlockSwComponent的时候需要选择我们的Type为Non-Volatile Memory Block的类型,这样,我们就得到了一个用于专门处理NV数据的SWC类型。但是该类型的SWC是不支持普通SWC的很多操作的,仅仅用于处理NV Data,代码可以由配置自动生成
Properties
这里可以配置NVRAM中的RAM Block 和ROM Block的一些选项
Data Type:该RAM Block的类型,这里需要注意的是,如果是使用的Fan-in的话,这里的类型一定要使用结构体类型,因为当多个SWC的数据存入一个RAM Block的时候,是需要多个数据进行暂存的。上图中的TestStruct是我新建的一个IDT数据类型
Periodic Trigger:如果我们配置了一个周期性的Runnable,那么这里是可以选择该Runnable的,作用就是当周期触发该Runnable时,该Runnable会执行将这个RAM Block写入NV的操作(通过NvM)
Data Reception Triggers:如果我们配置了一个Runnable,该Runnable的触发条件是On Data Reception,那么通过一个Data Mapping的操作,可以在这里显示所有的与本RAM Block关联的Data Reception Triggers Runnable
NV Block Data Mapping
这个Mapping的操作就是将SWC的Port与我们的RAM Block关联上,告诉DaVinci我们的Port传过来的数据要存放在哪个RAM Block的哪个数据中,或者我们的RAM Block里的数据要给哪些Port。
Service Needs(NvBlockNeeds)
之前讲过自下而上的Service Mapping操作,这里的Service Needs是自上而下的Service Mapping操作。作用是申明该SWC可能需要用到哪些Service函数,然后再进入BSW层去配置需要用到这些Service函数的功能。这里的NvBlockNeeds是一类特殊的Service Needs,因为它单独放在了NvBlockDescriptors里进行配置(但内容是一样的,只是位置不同罢了)。仅仅是NvBlockSwComponents有这个特性,如果不使用NvBlockSwComponents直接将Application SWC和NvM相连也是可以的,那么Application SWC的Service Needs就需要从其他地方来配置了。
![9489b06295f16d96fac70d18b9e6372c.gif](https://i-blog.csdnimg.cn/blog_migrate/1f9fd2813f51bb0cf387b8b43b2e67ea.gif)
2
C语言
11.2.3-11.3.3
a. gets_s函数
gets_s(words, STLEN);
gets_s()与fgets()的区别如下。
1、gets_s()只从标准输入中读取数据,所以不需要第3个参数。
2、如果gets_s()读到换行符,会丢弃它而不是储存它。
3、如果gets_s()读到最大字符数都没有读到换行符,会执行以下几步。首
先把目标数组中的首字符设置为空字符,读取并丢弃随后的输入直至读到换
行符或文件结尾,然后返回空指针。接着,调用依赖实现的“处理函数”(或
你选择的其他函数),可能会中止或退出程序。
第2个特性说明,只要输入行未超过最大字符数,gets_s()和gets()几乎一样,完全可以gets_s()替换gets()。
第3个特性说明,要使用这个函数还需要进一步学习。
比较一下 gets()、fgets()和 gets_s()的适用性。如果目标存储区装得下输入行,3 个函数都没问题。但是fgets()会保留输入末尾的换行符作为
字符串的一部分,要编写额外的代码将其替换成空字符。
如果输入行太长会怎样?使用gets()不安全,它会擦写现有数据,存在
安全隐患。gets_s()函数很安全,但是,如果并不希望程序中止或退出,就
要知道如何编写特殊的“处理函数”。另外,如果打算让程序继续运行,gets_s()会丢弃该输入行的其余字符,无论你是否需要。由此可见,当输入太长,超过数组可容纳的字符数时,fgets()函数最容易使用,而且可以选择不同的处理方式。
b.scanf()函数
scanf()和gets()或fgets()的区别在于它们如何确定字符串的末尾:
scanf()更像是“获取单词”函数,而不是“获取字符串”函数;如果预留的存储区装得下输入行,gets()和fgets()会读取第1个换行符之前所有的字符。
scanf()函数有两种方法确定输入结束。无论哪种方法,都从第1个非空白字符作为字符串的开始。如果使用%s转换说明,以下一个空白字符(空行、空格、制表符或换行符)作为字符串的结束(字符串不包括空白字符)。如果指定了字段宽度,如%10s,那么scanf()将读取10 个字符或读到第1个空白字符停止(先满足的条件即是结束输入的条件)
如下图为字段宽度和scanf()
看下面的程序:
下面是该程序的3个输出示例:
Please enter 2 names.
Jesse Jukes
I read the 2 names Jesse and Jukes.
Please enter 2 names.
Liza Applebottham
I read the 2 names Liza and Applebotth.
Please enter 2 names.
Portensia Callowit
I read the 2 names Porte and nsia.
第1个输出示例,两个名字的字符个数都未超过字段宽度。第2个输出示
例,只读入了Applebottham的前10个字符Applebotth(因为使用了%10s转换
说明)。第3个输出示例,Portensia的后4个字符nsia被写入name2中,因为第
2次调用scanf()时,从上一次调用结束的地方继续读取数据。在该例中,读
取的仍是Portensia中的字母。
scanf()和gets()类似,也存在一些潜在的缺点。如果输入行的内容过长,scanf()也会导致数据溢出。不过,在%s转换说明中使用字段宽度可防止溢出。
字符串输出
讨论完字符串输入,接下来我们讨论字符串输出。C有3个标准库函数,用于打印字符串:put()、fputs()和printf()。
c.puts()函数
puts()函数很容易使用,只需把字符串的地址作为参数传递给它即可。
如下图为puts()函数程序:该程序示例再次说明,用双引号括起来的内容是字符串常量,且被视为该字符串的地址。另外,储存字符串的数组名也被看作是地址。在第5个puts()调用中,表达式&str1[5]是str1数组的第6个元素(r),puts()从该元素
开始输出。与此类似,第6个puts()调用中,str2+4指向储存"pointer"中i的存储单元,puts()从这里开始输出。
puts()函数在遇到空字符时就会停止输出,所以必须确保有空字符
如下图程序操作是有问题的:
由于dont缺少一个表示结束的空字符,所以它不是一个字符串,因此puts()不知道在何处停止。它会一直打印dont后面内存中的内容,直到发现一个空字符为止。为了让puts()能尽快读到空字符,我们把dont放在side_a和side_b之间。
我们使用的编译器把side_a数组储存在dont数组之后,所以puts()一直输出至遇到side_a中的空字符。你所使用的编译器输出的内容可能不同,这取决于编译器如何在内存中储存数据。如果删除程序中的side_a和side_b数组会怎样?通常内存中有许多空字符,如果幸运的话,puts()很快就会发现一个。但是,这样做很不靠谱。
d.fputs()函数
fputs()函数是puts()针对文件定制的版本。它们的区别如下。
fputs()函数的第 2 个参数指明要写入数据的文件。如果要打印在显示器上,可以用定义在stdio.h中的stdout(标准输出)作为该参数。与puts()不同,fputs()不会在输出的末尾添加换行符。
e.printf()函数
和puts()一样,printf()也把字符串的地址作为参数。printf()函数用起来没有puts()函数那么方便,但是它更加多才多艺,因为它可以格式化不同的数据类型。
printf()不会自动在每个字符串末尾加上一个换行
符。因此,必须在参数中指明应该在哪里使用换行符。例如:
printf("%s\n", string);
和下面的语句效果相同:
puts(string);
如上所示,printf()的形式更复杂些,需要输入更多代码,而且计算机执行的时间也更长(但是你觉察不到)。然而,使用 printf()打印多个字符串更加简单。例如,下面的语句把 Well、用户名和一个#define定义的字符串
打印在一行:
printf("Well, %s, %s\n", name, MSG);
![f6048d0d9ecb1583c232e4d2275c8d5f.gif](https://i-blog.csdnimg.cn/blog_migrate/217a116e46217d297c99d2ecca5c867a.gif)
![27816a394db8e26b036ab9873e6d88d3.png](https://i-blog.csdnimg.cn/blog_migrate/053a87925e4de2e3e1c70390b82b71c6.png)
![2c571916d1422c37aa680d6aa70b635c.png](https://i-blog.csdnimg.cn/blog_migrate/0760cf9d5220f24ec3fe8646715beab2.jpeg)