I cannot understand the macros logic and the way they work...so I can make a mcp2515_init() function. If someone can explain I would be glad to listen,thanks for your time.
#define true 1
#define false 0
#define True 1
#define False 0
typedef _Bool bool;
#define RESET(x) _XRS(x)
#define SET(x) _XS(x)
#define TOGGLE(x) _XT(x)
#define SET_OUTPUT(x) _XSO(x)
#define SET_INPUT(x) _XSI(x)
#define IS_SET(x) _XR(x)
#define PORT(x) _port2(x)
#define DDR(x) _ddr2(x)
#define PIN(x) _pin2(x)
#define _XRS(x,y) PORT(x) &= ~(1<<y)
#define _XS(x,y) PORT(x) |= (1<<y)
#define _XT(x,y) PORT(x) ^= (1<<y)
#define _XSO(x,y) DDR(x) |= (1<<y)
#define _XSI(x,y) DDR(x) &= ~(1<<y)
#define _XR(x,y) ((PIN(x) & (1<<y)) != 0)
#define _port2(x) PORT ## x
#define _ddr2(x) DDR ## x
#define _pin2(x) PIN ## x
I will try to break it down, what you have is a set of bit manipulating macros flipping/setting/clearing one bit on a port they are a generic kind of macros and not specific to the SPI driver.
bit clear (reset)
#define _XRS(x,y) PORT(x) &= ~(1<<y)
AND port with every bit expect bit y on port x.
bit set
#define _XS(x,y) PORT(x) |= (1<<y)
OR port with only bit y set. This will set bit y and leave other unaffected.
toggle
#define _XT(x,y) PORT(x) ^= (1<<y)
XOR a bit with 1 will toggle its value 0 will keep its state.
This list of macros only take one argument
#define RESET(x) _XRS(x)
#define SET(x) _XS(x)
#define TOGGLE(x) _XT(x)
#define SET_OUTPUT(x) _XSO(x)
#define SET_INPUT(x) _XSI(x)
#define IS_SET(x) _XR(x)
so these macros does not look compatible with the as they take one parameter instead of two, but with the magic of macros it is possible to create an output of x,y for instance
#define GPIO1_PIN4 1,4
#define POWER_LED GPIO0,PIN2
will make SET(POWER_LED); a legal assignment.
The # and ## macros
#define _port2(x) PORT ## x
Are used to concatenate outputs from macros to create new structures read more here
So using all the macros _XT(2,15); will expand to
PORT2 = PORT2 ^ (1<<15)
I am personally not a fan of this kind of macros as it breaks how plain vanilla C works by hiding the assignments inside the macros, for instance this style cannot set multiple bits on the same port with single write. However it is legal C and it is common among some embedded systems development environments.
It would probably be easier to ignore the above macros and just write the configuration and data directly to the registers word by word.
Related
TL;DR;
How to get the macro name used for size of a constant size array declaration, from a callExpr -> arg_0 -> DeclRefExpr.
Detailed Problem statement:
Recently I started working on a challenge which requires source to source transformation tool for modifying
specific function calls with an additional argument. Reasearching about the ways i can acheive introduced me
to this amazing toolset Clang. I've been learning how to use different tools provided in libtooling to
acheive my goal. But now i'm stuck at a problem, seek your help here.
Considere the below program (dummy of my sources), my goal is to rewrite all calls to strcpy
function with a safe version of strcpy_s and add an additional parameter in the new function call
i.e - destination pointer maximum size. so, for the below program my refactored call would be like
strcpy_s(inStr, STR_MAX, argv[1]);
I wrote a RecursiveVisitor class and inspecting all function calls in VisitCallExpr method, to get max size
of the dest arg i'm getting VarDecl of the first agrument and trying to get the size (ConstArrayType). Since
the source file is already preprocessed i'm seeing 2049 as the size, but what i need is the macro STR_MAX in
this case. how can i get that?
(Creating replacements with this info and using RefactoringTool replacing them afterwards)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define STR_MAX 2049
int main(int argc, char **argv){
char inStr[STR_MAX];
if(argc>1){
//Clang tool required to transaform the below call into strncpy_s(inStr, STR_MAX, argv[1], strlen(argv[1]));
strcpy(inStr, argv[1]);
} else {
printf("\n not enough args");
return -1;
}
printf("got [%s]", inStr);
return 0;
}
As you noticed correctly, the source code is already preprocessed and it has all the macros expanded. Thus, the AST will simply have an integer expression as the size of array.
A little bit of information on source locations
NOTE: you can skip it and proceed straight to the solution below
The information about expanded macros is contained in source locations of AST nodes and usually can be retrieved using Lexer (Clang's lexer and preprocessor are very tightly connected and can be even considered one entity). It's a bare minimum and not very obvious to work with, but it is what it is.
As you are looking for a way to get the original macro name for a replacement, you only need to get the spelling (i.e. the way it was written in the original source code) and you don't need to carry much about macro definitions, function-style macros and their arguments, etc.
Clang has two types of different locations: SourceLocation and CharSourceLocation. The first one can be found pretty much everywhere through the AST. It refers to a position in terms of tokens. This explains why begin and end positions can be somewhat counterintuitive:
// clang::DeclRefExpr
//
// ┌─ begin location
foo(VeryLongButDescriptiveVariableName);
// └─ end location
// clang::BinaryOperator
//
// ┌─ begin location
int Result = LHS + RHS;
// └─ end location
As you can see, this type of source location points to the beginning of the corresponding token. CharSourceLocation on the other hand, points directly to the characters.
So, in order to get the original text of the expression, we need to convert SourceLocation's to CharSourceLocation's and get the corresponding text from the source.
The solution
I've modified your example to show other cases of macro expansions as well:
#define STR_MAX 2049
#define BAR(X) X
int main() {
char inStrDef[STR_MAX];
char inStrFunc[BAR(2049)];
char inStrFuncNested[BAR(BAR(STR_MAX))];
}
The following code:
// clang::VarDecl *VD;
// clang::ASTContext *Context;
auto &SM = Context->getSourceManager();
auto &LO = Context->getLangOpts();
auto DeclarationType = VD->getTypeSourceInfo()->getTypeLoc();
if (auto ArrayType = DeclarationType.getAs<ConstantArrayTypeLoc>()) {
auto *Size = ArrayType.getSizeExpr();
auto CharRange = Lexer::getAsCharRange(Size->getSourceRange(), SM, LO);
// Lexer gets text for [start, end) and we want him to grab the end as well
CharRange.setEnd(CharRange.getEnd().getLocWithOffset(1));
auto StringRep = Lexer::getSourceText(CharRange, SM, LO);
llvm::errs() << StringRep << "\n";
}
produces this output for the snippet:
STR_MAX
BAR(2049)
BAR(BAR(STR_MAX))
I hope this information is helpful. Happy hacking with Clang!
I'm trying to do some simulation of the RPL protocol using Contiki 3.0 and the Cooja Simulator. I'm using the sky motes and i'd like to see how the DODAG is formed and monitor the parameters of the network using the Collect View. I have some questions:
1) Where and how i can change the Objective function?
2) My sensors have 1mW energy consumption, i think that for real application is too much, since sensors needs to work for several years
3) Where i can change the other parameters of the simulation? Like Tx/Rx packets?
4) How I interpret the routing metric given in the collect view?
5) I noticed that when I change the position of a node the network is too much slow detecting the movement, RPL is not very fast, but in Cooja it takes too much time, is it possible? Do you have any suggestion for simulating moving sensors?
1) Your can set change objective function from contiki/core/net/rpl/rpl-conf.h
edit as per your requirement:
/*
* The objective function (OF) used by a RPL root is configurable through
* the RPL_CONF_OF_OCP parameter. This is defined as the objective code
* point (OCP) of the OF, RPL_OCP_OF0 or RPL_OCP_MRHOF. This flag is of
* no relevance to non-root nodes, which run the OF advertised in the
* instance they join.
* Make sure the selected of is inRPL_SUPPORTED_OFS.
*/
#ifdef RPL_CONF_OF_OCP
#define RPL_OF_OCP RPL_CONF_OF_OCP
#else /* RPL_CONF_OF_OCP */
#define RPL_OF_OCP RPL_OCP_MRHOF
#endif /* RPL_CONF_OF_OCP */
/*
* The set of objective functions supported at runtime. Nodes are only
* able to join instances that advertise an OF in this set. To include
* both OF0 and MRHOF, use {&rpl_of0, &rpl_mrhof}.
*/
#ifdef RPL_CONF_SUPPORTED_OFS
#define RPL_SUPPORTED_OFS RPL_CONF_SUPPORTED_OFS
#else /* RPL_CONF_SUPPORTED_OFS */
#define RPL_SUPPORTED_OFS {&rpl_mrhof}
#endif /* RPL_CONF_SUPPORTED_OFS */
/*
* Enable/disable RPL Metric Containers (MC). The actual MC in use
* for a given DODAG is decided at runtime, when joining. Note that
* OF0 (RFC6552) operates without MC, and so does MRHOF (RFC6719) when
* used with ETX as a metric (the rank is the metric). We disable MC
* by default, but note it must be enabled to support joining a DODAG
* that requires MC (e.g., MRHOF with a metric other than ETX).
*/
#ifdef RPL_CONF_WITH_MC
#define RPL_WITH_MC RPL_CONF_WITH_MC
#else /* RPL_CONF_WITH_MC */
#define RPL_WITH_MC 0
#endif /* RPL_CONF_WITH_MC */
2) Contiki provides radio duty cycle (RDC) mechanisms for long term operation of nodes.
Default is nullrdc in which node always remains on hence life is less. Set ContikiMAC for minimizing power of nodes.
goto contiki/core/contiki-default-conf.h and edit as per your requirement.
e.g.
#ifndef NETSTACK_CONF_RDC
/* #define NETSTACK_CONF_RDC nullrdc_driver */
#define NETSTACK_CONF_RDC contikimac_driver
#endif /* NETSTACK_CONF_RDC */
3) Tx/Rx can be set from Network visualizer itself. You can right click any node and edit tx/rx range as well as success ratio.
You can also edit the same in .csc (simulation) file.
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>100.0</transmitting_range>
<interference_range>120.0</interference_range>
<success_ratio_tx>0.9</success_ratio_tx>
<success_ratio_rx>0.9</success_ratio_rx>
</radiomedium>
4) You have to calculate various performance metrics. For that you have code script file yourself (tough part).
Or use these links
https://github.com/iloveyii/contiki_rpl/tree/master/perl
https://pdfs.semanticscholar.org/d319/4d5f43f1cd3995ba7c9e99776ac8f150d445.pdf
5) Use mobility plugin to simulate various mobility models.
https://anrg.usc.edu/contiki/index.php/Mobility_of_Nodes_in_Cooja
http://vrajesh2188.blogspot.com/2016/04/mobility-in-contiki-2.html
I developed a Cordova application and it went through a security review, one of the findings was related to a plugin I use to make curl requests. The finding is graded as Heigh vulnerability.
The finding is as follows:
Signed integer sizeof at line 143 of [some file] specifies size of memory to allocate.
#ifdef __LP64__
#define CURL_SIZEOF_LONG 8
#else
#define CURL_SIZEOF_LONG 4
#endif
#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
typedef char
__curl_rule_01__
[CurlchkszEQ(long, CURL_SIZEOF_LONG)];
This is an objective-c code and I am not familiar with it. So my question is what is this vulnerability and how to fix it?
This is my example I've found:
#define kNumberOfViews (37)
#define kViewsWide (5)
#define kViewMargin (2.0)
Why it cannot be like that?
#define kNumberOfViews 37
#define kViewsWide 5
#define kViewMargin 2.0
And what means k in front? Is there a some guide for it?
It is not really required in your example, but the use of parenthesis in defines is a useful approach to make sure your define states exactly what you mean in the context of the define and protects it from side effects when used in code.
E.g
#define VAR1 40
#define VAR2 20
#define SAVETYPING1 VAR1-VAR2
#define SAVETYPING2 (VAR1-VAR2)
Then in your code
foo(4*SAVETYPING1); // comes out as foo(140)
Is not the same as
foo(4*SAVETYPING2); // comes out as foo(80)
As for what the k prefix means. It is used for constants. Plenty of discussion here on the origins:
Objective C - Why do constants start with k
#define SOME_VALUE 1234
It is preprocessor directive. It means, that before your code is compiled, all occurrences of SOME_VALUE will be replaced by 1234. Alternative to this would be
const int kSomeValue = 1234;
For discussion about advantages of one or the other see
#define vs const in Objective-C
As for brackets - in more complex cases they are necessary exactly because preprocessor makes copy-paste with #define. Consider this example:
#define BIRTH_YEAR 1990
#define CURRENT_YEAR 2015
#define AGE CURRENT_YEAR - BIRTH_YEAR
...
// later in the code
int ageInMonths = AGE * 12;
Here one might expect that ageInMonths = 25 * 12, but instead it is computed as ageInMonths = 2015 - 1990 * 12 = 2015 - (1990 * 12). That is why correct definition of AGE should have been
#define AGE (CURRENT_YEAR - BIRTH_YEAR)
As for naming conventions, AFAIK for #define constants capital cases with underscores are used, and for const constants camel names with leading k are used.
k is just a hungarian notation convention to indicate that that is a constant value. Personally I find it dumb, but it is a convention that many people follow. It isn't required for the code to work at all.
I am not sure why the examples you saw had parens around them, but there is no need to have parentheses around #define values.
In lex & yacc there is a macro called YY_INPUT which can be redefined, for example in a such way
#define YY_INPUT(buf,result,maxlen) do { \
const int n = gzread(gz_yyin, buf, maxlen); \
if (n < 0) { \
int errNumber = 0; \
reportError( gzerror(gz_yyin, &errNumber)); } \
\
result = n > 0 ? n : YY_NULL; \
} while (0)
I have some grammar rule which called YYACCEPT macro.
If after YYACCEPT I called gztell (or ftell), then I got a wrong number, because parser already read some unnecessary data.
So how I can get current position if I have some rule which called YYACCEPT in it(one bad solution will be to read character by character)
(I have already done something like this:
#define YY_USER_ACTION do { \
current_position += yyleng; \
} while (0)
but seems its not work
)
You have to keep track of the offset yourself. A simple but annoying solution is to put:
offset += yyleng;
in every flex action. Fortunately, you can do this implicitly by defining the YY_USER_ACTION macro, which is executed just before the token action.
That might still not be right for your grammar, because bison often reads one token ahead. So you'll also need to attach the value of offset to each lexical token, most conveniently using the location facility (yylloc).
Edit: added more details on location tracking.
The following has not been tested. You should read the sections in both the flex and the bison manual about location tracking.
The yylloc global variable and its default type are included in the generated bison code if you use the --locations command line option or the %locations directive, or if you simply refer to a location value in some rule, using the # syntax, which is analogous to the $ syntax (that is, #n is the location value of the right-hand-side object whose semantic value is $n). Unfortunately, the default type for yylloc uses ints, which are not wide enough to hold a file offset, although you might not be planning on parsing files for which this matters. In any event, it's easy enough to change; you merely have to #define the YYLTYPE macro at the top of your bison file. The default YYLTYPE is:
typedef struct YYLTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
} YYLTYPE;
For a minimum modification, I'd suggest keeping the names unchanged; otherwise you'll also need to fix the YYLLOC_DEFAULT macro in your bison file. The default YYLLOC_DEFAULT ensures that non-terminals get a location value whose first_line and first_column members come from the first element in the non-terminal's RHS, and whose last_line and last_column members come from the last element. Since it is a macro, it will work with any assignable type for the various members, so it will be sufficient to change the column members to long, size_t or offset_t, as you feel appropriate:
#define YYLTYPE yyltype;
typedef struct yyltype {
int first_line;
offset_t first_column;
int last_line;
offset_t last_column;
} yyltype;
Then in your flex input, you could define the YY_USER_ACTION macro:
offset_t offset;
extern YYLTYPE yylloc;
#define YY_USER_ACTION \
offset += yyleng; \
yylloc.last_line = yylineno; \
yylloc.last_column = offset;
With all that done and appropriate initialization, you should be able to use the appropriate #n.last_column in the ACCEPT rule to extract the offset of the end of the last token in the accepted input.