임베디드 시스템 클래스 용으로 매우 간단한 커널을 작성하고 있습니다. 이 보드는 TI 스텔라리스 EKI-LM3S8962이다. 그것은 C를 실행하고 OLED 디스플레이가 있습니다. void 포인터에 문제가있어이를 참조 해제합니다. 어떤 도움이라도 대단히 감사합니다.임베디드 시스템의 단순 커널에서 함수 및 구조체에 void 포인터를 사용하는 구문
아주 작은 초기 목표는 함수 포인터와 struct 포인터를 전달하는 개념을 증명하는 것입니다. 이 방법은 내가 전달하는 데이터 구조체의 일부인 포인터 batteryStatePtr에 의해 지적 된 var batteryState에 액세스하는 방식입니까? 여기
void status (void* taskDataPtr) {
// make a temporary pointer to a Status Data Struct type
SDS* data;
// set data equal to the void* taskDataPtr now cast as a SDS pointer
data = (SDS*)(taskDataPtr);
(*data->batteryStatePtr)--;
...
내 코드의 매우 버전을 박탈하고, 중요한 영역은 CTRL-F에 의해 위치 될 수있다
struct MyStruct {
void (*taskPtr)(void*);
void* taskDataPtr;
};
typedef struct MyStruct TCB;
공극을 취하는 함수로 taskPtr 포인트
* "여기" arg로 그리고 void *를 데이터 구조체에가집니다. 개념의 증거로서 나는 가능한 한 작게 시작하고 있습니다. 상태와 표시의 두 가지 기능이 있습니다.typedef struct DisplayDataStruct {
uint* batteryStatePtr;
} DDS;
DDS DisplayData;
typedef struct StatusDataStruct {
uint* batteryStatePtr;
} SDS;
SDS StatusData;
status 전역 변수 batteryState가 주어진 taskDataPtr을 통해 감소합니다. 디스플레이는 문자열을 문자열에 연결하고 OLED에 표시합니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
void status (void* taskDataPtr);
void display (void* taskDataPtr);
void delay(uint msDelay);
// Declare a TCB structure
struct MyStruct {
void (*taskPtr)(void*);
void* taskDataPtr;
};
typedef struct MyStruct TCB;
// status var
uint batteryState = 200;
typedef struct DisplayDataStruct {
uint* batteryStatePtr;
} DDS;
DDS DisplayData;
typedef struct StatusDataStruct {
uint* batteryStatePtr;
} SDS;
SDS StatusData;
void main(void)
{
DisplayData.batteryStatePtr = &batteryState;
StatusData.batteryStatePtr = &batteryState;
int i = 0; // queue index
TCB* aTCBPtr;
TCB* queue[2];
TCB StatusTCB;
TCB DisplayTCB;
StatusTCB.taskPtr = status;
StatusTCB.taskDataPtr = (void*)&StatusData;
DisplayTCB.taskPtr = display;
DisplayTCB.taskDataPtr = (void*)&DisplayData;
// Initialize the task queue
queue[0] = &StatusTCB;
queue[1] = &DisplayTCB;
// schedule and dispatch the tasks
while(1)
{
for (i = 0; i < 2; i++) {
aTCBPtr = queue[i];
aTCBPtr->taskPtr((void*)(aTCBPtr->taskDataPtr));
}
systemState = (systemState + 1) % 100;
delay(50);
}
}
void status (void* taskDataPtr) {
// return if systemState != 0 aka run once every 5 sec
if (systemState) {
return;
}
// make a temporary pointer to a Status Data Struct type
SDS* data;
// set data equal to the void* taskDataPtr now cast as a SDS pointer
data = (SDS*)(taskDataPtr);
// HERE IS where I am stumped. Is (*data->batteryStatePtr)-- the way you do this????
// access the batteryStatePtr through the struct data
// then dereference the whole thing to get at batteryState
if ((*(data->batteryStatePtr)) > 0) {
// decrement batteryState
(*(data->batteryStatePtr))--;
}
return;
}
void display (void* taskDataPtr) {
// run once every 5 sec
if (systemState) {
return;
}
DDS* data;
data = (DDS*) taskDataPtr;
char hold[12] = "Batt: ";
char numHold[4];
sprintf(numHold, "%u", (*(data->batteryStatePtr)));
strcat(hold, numHold);
// display the string hold
RIT128x96x4StringDraw(hold, 15, 44, 15);
return;
}
// use for loops to waste cycles, delay taken in ms
void delay(uint msDelay)
{
// when i == 60000 and j == 100 function delays for ~ 7.6 sec
msDelay = msDelay * 150/19;
volatile unsigned long i = 0;
volatile unsigned int j = 0;
for (i = msDelay; i > 0; i--) {
for (j = 0; j < 100; j++);
}
return;
}
'(* (data-> batteryStatePtr)) - 괜찮을 것입니다 ... 거기에 문제가 있다고 생각되는 특별한 이유가 있습니까? – Dmitri
답변 해 주셔서 감사합니다. 나는 문제가 있다고 생각한다. 왜냐하면 그것이 작동하지 않고 포인터 전문성이 최소한이기 때문이다. 나는 그 문법을 쌓아 놓기를 원했을뿐입니다. 나는 알고 있습니다. – Bobby
컴파일러에서 경고를 표시합니까? 그리고'systemState'는 어디에 선언 되었습니까? – Dmitri