0. 写一个函数,将变量从 little endian转换成 big endian
1. 写一段代码,确定系统是big endian 还是 little endian
2. 写一个struct,初始化,并做为函数输入【分别传原值 / 传指针】
3. 写一个array,初始化,并做为函数输入【分别传原值 / 传指针】 // 不要传原值,not a good idea + Enum as function input
4. 在 struct 里面使用 bit field
5. 在 union 里面使用,并且利用 union 的优势,把 char 变量 拼接成 int 变量
6. structure padding的代码例子, and how to avoid it (using compiler #pragma keyword)
7.
uint8_t findIndex(uint32_t dtcs[], uint8_t num_elements, uint32_t dtc_of_interest)
8.
void CalcDistances(uint32_t odometer_reading, Mode mode)
9.
10.
typedef struct
{
uint32_t odometer;
uint8_t wakeupReason;
uint16_t powerMode;
}SnapShot;
void SnapshotAdd(SnapShot s)
SnapShot RetrieveSnapshot(uint8_t index)
11.
array as function input is always working as passing the address of the array
注意line16, func(a) 而不是 func(a[4])
12.
access the fixed memory location in embedded C
LeetCode里面那些数组排序基础题
interrupt函数的注意事项【不传参,没有返回值,不能调用可重如函数,避免浮点数运算】
从汇编语言的角度看看函数调用,局部变量出入栈的过程 Compiler Explorer
0.
#include <stdio.h>
typedef unsigned int uint32;
uint32 endian(uint32 data)
{
uint32 ret = 0;
uint32 a = (data & 0xFF000000) >>24;
uint32 b = (data & 0x00FF0000) >>8;
uint32 c = (data & 0x0000FF00) <<8;
uint32 d = (data & 0x000000FF) <<24;
ret = a + b + c + d;
return ret;
}
int main()
{
uint32 a = 0x76543210;
a = endian(a);
printf("Hello, World!\n");
printf("value is 0x%x\n", a);
return 0;
}
should use bit manipulate "&" rather than pointer for this question
1.
// Online C compiler to run C program online
#include <stdio.h>
int main() {
unsigned int a = 0x76543210;
unsigned char *c = (unsigned char *)&a;
// Write C code here
printf("Hello world\n");
printf("the value of c[0] is 0x%x\n",*c);
printf("the value of c[1] is 0x%x\n",*(c+1));
printf("the value of c[2] is 0x%x\n",*(c+2));
printf("the value of c[3] is 0x%x\n",*(c+3));
if(*c == 0x76)
{
printf("this machine is big endiness");
}
else
{
printf("this value is little endiness");
}
return 0;
}
2.
Laptop2-> ProductId 等价于
(*
Laptop2). ProductId
#include <stdio.h>
typedef struct
{
int a;
char b;
int c[2];
}Note;
// 传值
void printNote( Note note )
{
printf("the value of a is %d\n",note.a);
printf("the value of b is %d\n",note.b);
printf("the value of c[0] is %d\n",note.c[0]);
}
// 传指针
void printNote_P( Note *P_note)
{
printf("the value of a is %d\n",P_note->a);
printf("the value of c[1] is %d\n",P_note->c[1]);
}
int main()
{
Note note1, *note2;
note1.a = 5;
note1.b = 10;
note1.c[0] = 15;
note1.c[1] = 20;
printNote(note1);
printf("Hello, World!\n");
printNote_P(¬e1);
return 0;
}
3.
// Online C compiler to run C program online
#include <stdio.h>
int func_P(int *a)
{
printf("the value of a[0] is %d\n",*a);
printf("the value of a[1] is %d\n",*(a+1));
return 0;
}
int main() {
int array[2] = {5,10};
// Write C code here
printf("Hello world");
func_P(array);
return 0;
}
4.
// Online C compiler to run C program online
#include <stdio.h>
typedef struct
{
unsigned int a:3; // 3-bit, max value is 7
}Age;
int main() {
Age age;
// Write C code here
printf("Hello world");
age.a = 1;
printf("the value of age.a is %d\n",age.a);
age.a = 7;
printf("the value of age.a is %d\n",age.a);
age.a = 10;
printf("the value of age.a is %d\n",age.a);
return 0;
}
注意如果a 是 int 而不是 unsigned int,那么结果又不一样
5.
// Online C compiler to run C program online
#include <stdio.h>
typedef union
{
unsigned char a[4];
unsigned int b;
}PwmReg_1;
typedef struct {
volatile unsigned int Bit0:1;
volatile unsigned int Bit1:1;
volatile unsigned int Bit2:1;
volatile unsigned int Bit3:1;
volatile unsigned int Bit4:1;
volatile unsigned int Bit5:1;
volatile unsigned int Bit6:1;
volatile unsigned int Bit7:1;
}SPortPin;
typedef union
{
unsigned char a;
SPortPin GPIO_pin;
}PwmReg_2;
/
int main() {
PwmReg_1 pwmReg_1;
pwmReg_1.a[0] = 1;
pwmReg_1.a[1] = 2;
pwmReg_1.a[2] = 3;
pwmReg_1.a[3] = 4;
printf("the value of pwmReg_1.b is 0x%x\n",pwmReg_1.b);
// Write C code here
printf("Hello world");
return 0;
}
倒数第3行的printf也可以用来测试big endiness还是little endiness
注意如果传给函数,这种struct / union都是传递指针的
volatile UGpioPort *pUGpioPort =(volatile UGpioPort*)0xE002C000;/*Address*/
pUGpioPort->PORT=0x00000000;
6.
// Online C compiler to run C program online
#include <stdio.h>
typedef struct
{
int a;
char b;
char c;
}M;
typedef struct
{
char a;
int b;
char c;
}N;
int main() {
// Write C code here
printf("Hello world\n");
M m;
N n;
printf("the length of m is %d\n", sizeof(m)); // 4+ (2+2)
printf("the length of n is %d\n", sizeof(n)); // 4 + 4 +4
return 0;
}
7.
#include <stdio.h>
typedef unsigned int uint32_t; // typedef to follow MISRA rule
typedef unsigned char uint8_t;
// pass pointer of array as function input could be more efficient
uint8_t findIndex(uint32_t dtcs[], uint8_t num_elements, uint32_t dtc_of_interest)
{
uint8_t ret=0xFF; // return 0xFF is DTC is not found
uint8_t i=0;
for(i=0; i<num_elements; i++)
{
if(dtc_of_interest == dtcs[i]) // avoid miss typing
{
ret = i;
break; // break the for loop when DTC is found
}
}
return ret;
}
int main()
{
// DTC: 3 byte ID + 1 byte DTC status
uint32_t DTC_array[4] = {0x00100000,0x01100000,0x10000000,0x11100000};
uint8_t returnvalue;
// testcase 1, for existing DTC
returnvalue = findIndex(DTC_array, 4, 0x01100000);
printf("the index of interest DTC is %d\n",returnvalue);
// testcase 2, for non-exist DTC
returnvalue = findIndex(DTC_array, 4, 0x01100100);
printf("the index of interest DTC is %d\n",returnvalue);
return 0;
}
Note:
1. typedef which is MISRA rule
1. Global function <name> that are only used within the same file should be declared using the static storage-class specifier. |
2. typedefs that indicate size and signedness should be used instead of the basic C types |
3. The global variable should be initialized
|
IBM Docs (MISRA 2004)
2. DTC 4 bytes, 3 bytes ID + 1 byte current status
https://karthik-balu.github.io/projects/2017/11/25/DTCs
3. DTC status byte
4. could pass array without length (unsized array) as function input, but better to pass with pointer
https://www.tutorialspoint.com/cprogramming/c_passing_arrays_to_functions.htm
5. better habit: avoid miss typing
if(dtc_of_interest == dtcs[i])
6. when DTC is not found, return 0xFF (two test case, one for the exist DTC, another for DTC not found)
7. break to stop over searching
8. try pass pointer instead of array as function input by myself
9. how to take benefit with ordered array?
8.
#include <stdio.h>
typedef unsigned int uint32_t; // if odomteter is float?
typedef unsigned char uint8_t;
typedef enum{
Auto, Sport
}Mode;
uint32_t odometer_reading_previous = 0; // because it is unsigned int type, so it should be fine when odometer overflow (could only overflow once because of the 10ms period)
uint32_t distance_Auto = 0;
uint32_t distance_Sport = 0;
uint8_t Init_Flag = 1;
// how calibration data is saved an reused after rebooting?
// 主要是calibration 数据下电的时候存到哪,然后上电的时候怎么读出来
void CalcDistances(uint32_t odometer_reading, Mode mode)
{
// first execution
if (1 == Init_Flag)
{
odometer_reading_previous = odometer_reading;
Init_Flag = 0;
}
else if (0 == Init_Flag)
{
// Auto mode
if (Auto == mode)
{
distance_Auto += odometer_reading - odometer_reading_previous;
odometer_reading_previous = odometer_reading;
}
// Sport mode
else
{
distance_Sport += odometer_reading - odometer_reading_previous;
odometer_reading_previous = odometer_reading;
}
}
else
{
// Init_Flag value error
}
}
int main()
{
// test case
uint32_t odometer_array[10] ={10,20,26,30,40,51,55,60,74,80};
uint8_t mode_array[10] ={1,1,1,0,0,1,0,1,1,1};
Mode mode_S = Sport;
Mode mode_A = Auto;
uint8_t i =0;
for(i=0; i<10; i++)
{
if(mode_array[i] ==1)
{
CalcDistances(odometer_array[i], mode_S); // odometer_array[i] could be function input
}
else
{
CalcDistances(odometer_array[i], mode_A);
}
printf("time %d, mode %d: the distance of Auto is %d, the distance of Sport is %d\n",i,mode_array[i],distance_Auto,distance_Sport);
}
return 0;
}
0. enum for Mode
1. what would happen if odometer is float?
2. it is ok when odometer overflow, because it is unsigned type
3. for the first time function run, what would happen? how calibration data is saved when power down, 上电的时候又怎么读出来? (.bss .data , memory map keyword, linker file allocation?)
4. odometer_array[i] 带变量i 可以直接当函数输入,挺有意思
5. what does the 10ms period matter?
9.
#include <stdio.h>
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
#define SET_BIT(variable,position) ( variable |= ( 1u<<position) )
#define CLEAR_BIT(variable,position) ( variable &= ~( 1u<<position ) )
#define TOGGLE_BIT(variable,position) ( variable ^= ( 1u<<position ) )
int main()
{
uint32_t a = 0x8FF;
uint8_t b = 9;
uint8_t c = 11;
// test case 1
printf("the original value is 0x%x\n",a);
SET_BIT(a,b);
printf("the output of SET_BIT %d is 0x%x\n",b,a);
printf("\n");
//test case 2
a = 0x8FF;
printf("the original value is 0x%x\n",a);
CLEAR_BIT(a,c);
printf("the output of CLEAR_BIT %d is 0x%x\n",c,a);
printf("\n");
// test case 3
a = 0x8FF;
printf("the original value is 0x%x\n",a);
TOGGLE_BIT(a,b);
printf("the output of TOGGLE_BIT %d is 0x%x\n",b,a);
return 0;
}
10.
#include <stdio.h>
// reserve for test purpose
#define testcase_1
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef signed char int8_t;
typedef struct
{
uint32_t odometer;
uint8_t wakeupReason;
uint16_t powerMode;
}SnapShot;
typedef struct
{
SnapShot snapshots[10];
int8_t rear; // mark the last valid element of snapshots[]
}SnapShot_Quene;
SnapShot_Quene snapshots_quene;
void SnapshotAdd(SnapShot s)
{
uint8_t i = 0;
// snapshots quene Not FULL (size less than 10)
if(snapshots_quene.rear < 9)
{
snapshots_quene.rear++;
snapshots_quene.snapshots[snapshots_quene.rear] = s;
}
// the snapshots quene FULL (snapshots_quene.rear equal to 9)
else
{
// snapshots element 0 - 8, left shift one
for(i=0; i<9; i++)
{
snapshots_quene.snapshots[i] = snapshots_quene.snapshots[i+1];
}
// snapshots element 9, equal to s
snapshots_quene.snapshots[9] = s;
}
}
SnapShot RetrieveSnapshot(uint8_t index)
{
SnapShot ret = {0xFFFFFFF, 0xFF, 0xFFFF}; // 结构体定义用分号,初始化用逗号
// if index is larger than existing length
if(index > snapshots_quene.rear)
{
// for debugging only, remove when development done
printf("the snapshots[%d].odometer equal to 0x%x\n",index,ret.odometer);
printf("the snapshots[%d].wakeupReason equal to 0x%x\n",index,ret.wakeupReason);
printf("the snapshots[%d].powerMode equal to 0x%x\n",index,ret.powerMode);
return ret;
}
else
{
ret = snapshots_quene.snapshots[index];
}
// for debugging only, remove when development done
printf("the snapshots[%d].odometer equal to 0x%x\n",index,ret.odometer);
printf("the snapshots[%d].wakeupReason equal to 0x%x\n",index,ret.wakeupReason);
printf("the snapshots[%d].powerMode equal to 0x%x\n",index,ret.powerMode);
return ret;
}
int main()
{
// snapshots_quene init
snapshots_quene.rear = -1;
uint8_t i = 0; // should not use the same name i for MISRA rule, but this is test code, so...
SnapShot snapshotss[10];
for(i=0; i<8; i++)
{
snapshotss[i].odometer = i;
snapshotss[i].wakeupReason =i;
snapshotss[i].powerMode =i;
SnapshotAdd(snapshotss[i]);
}
#if defined testcase_1
// test case 1
printf("test case 1:\n");
RetrieveSnapshot(4); // expect to work well
RetrieveSnapshot(8); // expect to out of boundry
RetrieveSnapshot(9); // expect to out of boundry
#elif defined testcase_2
// test case 2
printf("test case 2:\n");
SnapShot add = {8,1,9};
SnapshotAdd(add);
RetrieveSnapshot(4); // expect to work well
RetrieveSnapshot(8); // expect to work well
RetrieveSnapshot(9); // expect to out of boundry
#elif defined testcase_3
// test case 3
printf("test case 3:\n");
SnapShot add = {8,1,9};
SnapshotAdd(add);
SnapshotAdd(add);
SnapshotAdd(add);
RetrieveSnapshot(4); // expect to work well, left shift once
RetrieveSnapshot(8); // expect to work well
RetrieveSnapshot(9); // expect to work well
#endif
return 0;
}
1. #define #if defined #endif for test case
2. short for 16-bit
3. struct array as struct element
4. try to pass struct pointer as function input
5. 结构体定义用分号,初始化用逗号
6.
12.
volatile uint32_t * flagAddress = (volatile uint32_t *)0x40000000;
//write to the address
* flagAddress = 32;