HAL_FLASHEx_DATAEEPROM_Program hard fault - c

I use my function to write a string to the eeprom bank of the stm32l073.
Directly after the function HAL_FLASHEx_DATAEEPROM_Program will be called, the sytem goes into HardFault:
Debug Stack
The address i want to write is in the correct space 0x080803b4: MemoryMap
Do you see any problem in that process? I tried also to erase this WORD before write, but same problem with that write function.
HAL_StatusTypeDef eepromDrv_WriteWORD(uint32_t address, const uint32_t* pData, uint16_t dataLength)
{
bool bSuccess = true;
uint32_t ui32Addr = 0;
HAL_StatusTypeDef status = HAL_ERROR;
HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(); // Only Erase befor Write, when EEPROM_READ != DATA
HAL_FLASHEx_DATAEEPROM_Unlock();
for (ui32Addr=0;ui32Addr < dataLength; ui32Addr+=4,pData++)
{
if ((HAL_FLASHEx_DATAEEPROM_Program( FLASH_TYPEPROGRAMDATA_WORD, address + ui32Addr, *pData)) != HAL_OK)
{
bSuccess = false;
}
}
HAL_FLASHEx_DATAEEPROM_Lock();
if(true == bSuccess)
{
status = HAL_OK;
}
return status;
}

Related

How do I copy values from one integer array into another integer array using only the keyboard to fill them?

I am trying to store values received from a non-blocking UART protocol. I enter characters from my keyboard and they are stored in an array called buffer that holds the value. I then want to fill a new array called newbuffer using the value from buffer array and then clear the value in buffer array so it is ready to receive another value from the keyboard.
Here is my initialization:
uint8_t buffer[2] = {0}; //initialize array for receiving keyboard input
uint8_t newbuffer[256] = {0}; //initialize array to store keyboard input from buffer array
int i = 0; //array index variable
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_EVEN;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
Here is the callback routine after I have entered my first character. I could really use some help with this part!!!
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//Prevent unused argument(s) compilation warning
UNUSED(huart);
for (i = 0; i < sizeof(newbuffer); i++)
{
newbuffer[i] = buffer[0]; //put value entered from keyboard into newbuffer array
memset(buffer, 0, sizeof(buffer)); //clear buffer array for next value
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call interrupt that handles entering keyboard values
}
printf("%d", newbuffer);
}
This is the interrupt function for getting keyboard values, in case you need to see that.
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint16_t *tmp;
/* Check that a Rx process is ongoing */
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
if (huart->Init.WordLength == UART_WORDLENGTH_9B)
{
tmp = (uint16_t *) huart->pRxBuffPtr;
if (huart->Init.Parity == UART_PARITY_NONE)
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2U;
}
else
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1U;
}
}
else
{
if (huart->Init.Parity == UART_PARITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
}
if (--huart->RxXferCount == 0U)
{
/* Disable the UART Data Register not empty Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
/* Rx process is completed, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx complete callback*/
huart->RxCpltCallback(huart);
#else
/*Call legacy weak Rx complete callback*/
HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
THANKS IN ADVANCE :)
Have you realized that you are copying exactly 1 byte in the for loop inside HAL_UART_RxCpltCallback, whereas array buffer is two bytes in size ?
This sentence: newbuffer[i] = buffer[0]; is just copying the first byte.
If you are reading from the keyboard you are probably getting scan codes. Scan codes are not all one byte, but many of them. Depending on the keys they can be up to three bytes: https://en.wikipedia.org/wiki/Scancode.
I solved the problem. The issue was with having the logic in a for loop. Since the size of newbuffer is 256, the program would not exit the for loop unless all of the characters had been entered and newbuffer was full. By taking my logic out of the for loop, the function could complete and return to main to be recalled in the main loop when the next character was entered.
I also added a flag variable so that I can print the string that was entered when the user types the carriage return button.
Receive Callback Routine:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//Prevent unused argument(s) compilation warning
UNUSED(huart);
newbuffer[i] = buffer[0] //put value entered from keyboard into newbuffer array
if (newbuffer[i] == '\r') //if user enters a carriage return the input will be flagged and trigger the while loop to print the string
{
flag = 1;
}
else
{
flag = 0;
}
memset(buffer, 0, sizeof(buffer)); //clear buffer array to receive next keyboard value
i++; //increment newbuffer index
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call interrupt that handles entering keyboard values
Main:
int main(void)
{
HAL_Init();
/* Configure the system clock to 180 MHz */
SystemClock_Config();
/* Initialize BSP Led for LED2 */
BSP_LED_Init(LED2);
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_EVEN;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
NVIC_SetPriority(USART3_IRQn, (1u << __NVIC_PRIO_BITS) - 5u); //set interrupt priority
NVIC_EnableIRQ(USART3_IRQn);
/*INTERRUPT METHOD*/
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call UART receive interrupt to get keyboard input
//Infinite loop
while (1)
{
//output a message in Hyperterminal requesting keyboard input
printf("\n\rEnter your string: ");
NVIC_DisableIRQ(USART3_IRQn);
if (flag == 1)
{
printf("%s", newbuffer); //string is printed if user enters a carriage return
flag = 0; //reset flag so the interrupt routine can look for another carriage return
memset(newbuffer, 0, sizeof(newbuffer)); //clear newbuffer so it is ready to store a new string
i = 0; //reset index so newbuffer begins storing its new string starting at newbuffer[0]
}
NVIC_EnableIRQ(USART3_IRQn);
HAL_Delay (1000);
}

Struct memory allocation issues for message buffer

I'm trying to use static structs as a buffer for incoming messages, in order to avoid checking the buffer on the MCP2515-external unit. An ISR enters the function with a can_message* value 255 to actually read new messages from my MCP2515.
Other applications register an ID in the message passed as argument, in order to check if the buffer holds any messages with the same value.
This returns wrong IDs, and the rest of the datafields are 0 and uninitialized. What is wrong?
can_message struct:
typedef struct
{
uint8_t id;
uint8_t datalength;
uint8_t data[8];
}can_message;
int CAN_message_receive(can_message* message)
{
static volatile can_message* buffers = (volatile can_message*)0x18FF;
static int birth = 1;
if(birth)
{
for (int i; i < CAN_MESSAGE_UNIQUE_IDS; i++)
{
//These structs gets addresses outside SRAM
buffers[i] = (can_message){0,0,0};
}
birth = 0;
}
if (message == CAN_UPDATE_MESSAGES)
{
/* Sorts messages <3 */
can_message currentMessage;
//These functions are working:
CAN_message_get_from_MCP_buf(&currentMessage, 0);
buffers[currentMessage.id] = currentMessage;
CAN_message_get_from_MCP_buf(&currentMessage, 1);
buffers[currentMessage.id] = currentMessage;
return 0; //returns nothing !
}
if(buffers[message->id].id != 0)
{
printf("test\n");
//This copy gives wrong id and data:
memcpy(message, &buffers[message->id], sizeof(can_message));
buffers[message->id].id = 0;
return 0;
}
return -1;
}
Edit 1:
I did however notice that any buffers[i]-struct gets a totally different address than expected. It does not use the addresses following 0x18FF on the SRAM. Is there any way to change this?
Edit 2:
This is my main-loop:
while (1) {
//printf("tx buf ready: %d\n", MCP2515_TX_buf_empty(0));
//CAN_Loopback_test();
_delay_ms(500);
value = USART_ReadByte(0);
CAN_message_receive(&msg);
printf("CAN_receive: ID: %d, datalength: %d, data: \n",msg.id);
for (int k; k < msg.datalength; k++)
{
printf("%d, ",msg.data[k]);
}
printf("\n");
}
Edit 3: Changing the buffer-pointer to array solved the issue. (It does no longer use the SRAM, but whatever floats my boat)
int CAN_message_receive(can_message* message)
{
static can_message buffers[CAN_MESSAGE_UNIQUE_IDS];
static int birth = 1;
if(birth)
{
for (int i; i < CAN_MESSAGE_UNIQUE_IDS*10; i++)
{
*(char*)(0x18FF+i) = 0;
printf("buffers: %X\n", &buffers[i]);
}
birth = 0;
}
Solved!
Pointer to buffers changed to buffer-array:
int CAN_message_receive(can_message* message)
{
static can_message buffers[CAN_MESSAGE_UNIQUE_IDS];
static int birth = 1;
if(birth)
{
for (int i; i < CAN_MESSAGE_UNIQUE_IDS*10; i++)
{
*(char*)(0x18FF+i) = 0;
printf("buffers: %X\n", &buffers[i]);
}
birth = 0;
}
I would strongly suggest to decouple the ISR logic with the programs own message cache logic. Also the initializing logic with the birth variable looks unnecessary.
I would setup some ring buffer that the ISR can write messages to and from that the main code reads the data into the ID-lookup-buffer.
This would ensure that message updates does not interfere with readouts (at least if you check the read/write indices to your ring buffer) and also eliminates the need to put Mutexes around your whole message buffer.
Currently it smells very badly because of missing read/write synchronization.
// global
#define CAN_MESSAGE_UNIQUE_IDS 50
static can_message g_can_messagebuffers[CAN_MESSAGE_UNIQUE_IDS];
#define MAX_RECEIVEBUFFER 8
static volatile can_message g_can_ringbuffer[MAX_RECEIVEBUFFER];
static volatile int g_can_ringbufferRead = 0;
static volatile int g_can_ringbufferWrite = 0;
// called from ISR
void GetNewMessages()
{
// todo: check ring buffer overflow
can_message currentMessage;
CAN_message_get_from_MCP_buf(&g_can_ringbuffer[g_can_ringbufferWrite], 0);
g_can_ringbufferWrite = (g_can_ringbufferWrite + 1) % MAX_RECEIVEBUFFER;
CAN_message_get_from_MCP_buf(&g_can_ringbuffer[g_can_ringbufferWrite], 1);
g_can_ringbufferWrite = (g_can_ringbufferWrite + 1) % MAX_RECEIVEBUFFER;
}
// called from main loop
void handleNewMessages()
{
while(g_can_ringbufferRead != g_can_ringbufferWrite){
const can_message* currentMessage = &g_can_ringbuffer[g_can_ringbufferRead];
if(currentMessage->id < CAN_MESSAGE_UNIQUE_IDS)
{
g_can_messagebuffers[currentMessage->id] = *currentMessage;
}
g_can_ringbufferRead = (g_can_ringbufferRead + 1) % MAX_RECEIVEBUFFER;
}
}
// called from whoever wants to know
// todo:
// really required a by value interface?
// would it not be sufficient to return a pointer and
// provide an additional interface to mark the message as used?
int getMsg(can_message* message)
{
if(buffers[message->id].id != 0)
{
printf("test\n");
*message = &g_can_messagebuffers[message->id];
g_can_messagebuffers[message->id].id = 0;
return 0;
}
return -1;
}
// alternative to above
const can_message* getMsg(int id)
{
if( (id < CAN_MESSAGE_UNIQUE_IDS)
&& (g_can_messagebuffers[id] != 0))
{
return &g_can_messagebuffers[id].id;
}
return NULL;
}
void invalidateMsg(int id)
{
if(id < CAN_MESSAGE_UNIQUE_IDS)
{
g_can_messagebuffers[id] = 0;
}
}
edit:
after your changes to an message array instead some strange pointer, there is also no need for the setup routine for this code.
edit:
if your micro controller already has a buffer for received messages, then may be it is unnecessary at all to register a ISR and you could empty it from the mainloop directly into your own id-lookup buffer (assuming the mainloop is fast enough)

How to continually print output inside a switch statement?

I have been trying to continually print the PWM output of pin 3 inside the switch statement condition but it only prints once. Can I continually print it in serial monitor until it meets the second conditon? or use a while loop? or a if else ?
Here is my code I also have a code with a similar function but it uses if else but still it only prints once
void loop() {
// if there's any serial available, read it:
while (Serial.available() > 0) {
int InitVal = Serial.parseInt();
int red = Serial.parseInt();
switch(InitVal) {
case 1:
if (Serial.read() == '\n') {
analogWrite(redPin, red);
Serial.println(red);
Serial.write(red);
}
break;
case 0:
analogWrite(redPin, 0);
Serial.println(0);
Serial.write(0);
break;
}
}
}
I'am planning to inter-phase this with a GUI . A GUI sends ascii to the arduino reads it then sends the output value to the GUI.
Example
1.GUI sends [1,123] : 1 = the trigger point for the switch statement ; 123 = PWM value.
Arduino receives instructions and it prints out the pwm value
GUI receives pwm value and displays it
Revised code: Stuck at the last while loop maybe i could use a threading function in arduino so that the last while loop would be satisfied/dissatisfied?
void loop() {
int InitVal = 0;
// if there's any serial available, read it:
while (Serial.available() > 0) {
int InitVal = Serial.parseInt();
int red = Serial.parseInt();
switch(InitVal) {
case 1:
if (Serial.read() == '\n') {
InitVal = 1;
//analogWrite(redPin, red);
//Serial.println(red);
// Serial.write(red);
}
break;
case 0:
InitVal = 0;
//analogWrite(redPin, 0);
//Serial.println(0);
//Serial.write(0);
break;
}
if (InitVal) /* when enabled, blink leds */ {
delay(20);
while (InitVal == 1) /* loop forever */{
Serial.println(red);
Serial.write(red);
delay(20);
}
}
}
}
I discarded Serial.parseInt() function, removed the switch statments and followed #Arno Bozo advise on serial listening while following this tutorial on http://forum.arduino.cc/index.php?topic=396450.0
I came up with what I want and here is the code
const int redPin = 3;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
boolean newData = false;
int InitVal = 0; // change to init value or red
int red = 0;
void setup() {
// initialize serial:
Serial.begin(9600);
// make the pins outputs:
pinMode(redPin, OUTPUT);
}
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
One();
newData = false;
}
else {
Zero();
}
}
///////////////////// ///////////////////// /////////////////////
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
///////////////////// ///////////////////// /////////////////////
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,","); // get the first part - the string
InitVal = atoi(strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
red = atoi(strtokIndx); // convert this part to an integer
}
///////////////////// ///////////////////// /////////////////////
void One() {
if (InitVal == 0){
delay(20);
Serial.println(0);
delay(20);
}
}
///////////////////// ///////////////////// /////////////////////
void Zero() {
if (InitVal == 1){
delay(20);
Serial.println(red);
delay(20);
}
}
In Summary the code works like this
1.In serial monitor send this <1,123> : 1 = the trigger point for the switch statement ; 123 = PWM value.
Arduino receives instructions and it prints out the pwm value
If you send <0,123> it prints a zero once
I post a refined code here. The architecture may be reused for serial treatment. I have written it as an example for people I meet and who are learning with arduino.
I have made comments and explanation of ways to avoid delay. Here it is used to print current value of pwm every 1s, without stopping with a delay(1000).
#include <Arduino.h>
// with schedule(f,i) , the function f() will be called every i ms
// schedule(f,i) lines are put in loop() function
// f is of type void f(void)
#define schedule(f,i) {static unsigned long l=0;unsigned long c=millis();if((unsigned long)(c-l)>=i){l=c;f();}}
const int ledPin = 13;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
boolean newCommandHasArrived=false, newParsedCommand=false;
String personalSerialBuffer=""; // char[] would be better; but String are so convenient
enum ECommand {ecmdNoPwm=0, ecmdPwm=1, ecmdBad=10 };
ECommand cmd=ecmdNoPwm;
int cmdArg=0;
boolean readSerialBuffer(String &personalSerialBuffer);
boolean parseCommand(String &apersonalSerialBuffer, ECommand &acmd, int &acmdArg);
void executeCommand(ECommand acmd, int &acmdArg);
void printCurrentValue() {Serial.println(String("cval:") + cmdArg);}
void loop() {
// transfer serial buffer in personal buffer
newCommandHasArrived = readSerialBuffer(personalSerialBuffer);
if (newCommandHasArrived) {
newCommandHasArrived = false;
newParsedCommand = parseCommand(personalSerialBuffer, cmd, cmdArg);
}
if (newParsedCommand) {
newParsedCommand = false;
executeCommand(cmd, cmdArg);
}
// I print current value every 1000ms
//delay(1000); // you can often use delay without pb, but it is a bad usage
// Here I provide you with a quick way to execute a task every 1000ms
{
const unsigned long delayBetweenExecution=1000;
static unsigned long lastTime=0;
unsigned long current = millis();
// note that C++ says that overflow on unsigned is well defined
// it calculates modulo arithmetic
if ((unsigned long)(millis() - lastTime) >= delayBetweenExecution) {
lastTime = current;
Serial.println(String("cval:") + cmdArg);
}
}
// We can make it shorter thanks to a macro:
// but you have to define a void function(void) that uses only global variable
// because it has no argument :
// void printCurrentValue() {Serial.print(String("cval:") + cmdArg);}
//schedule(printCurrentValue, 1000);
}
boolean readSerialBuffer(String &personalSerialBuffer) {
if (Serial.available() > 0) {
personalSerialBuffer.concat(Serial.readString());
}
// the frame is considered finished, if it ends with \n
if (personalSerialBuffer.endsWith("\n"))
return true;
else
return false;
}
boolean parseCommand(String &apersonalSerialBuffer, ECommand &acmd, int &acmdArg) {
// format [ 1, 123]\n
// I omit [ then I read first int : 1
// Note: I cannot detect if no int is found because it will return 0 that is a valid cmd
int readCmd = apersonalSerialBuffer.substring(1).toInt();
// conversion readCmd to acmd
switch (readCmd) {
case 0:
acmd = ecmdNoPwm; break;
case 1:
acmd = ecmdPwm; break;
default:
Serial.println(String("new command unknown: ") +
apersonalSerialBuffer);
apersonalSerialBuffer = "";
return false;
}
// find beginning of 2nd part, separated by ','
int sepPos = apersonalSerialBuffer.indexOf(',');
// no ',' : indexOf returns -1
if (sepPos == -1) {
Serial.println(String("new command could not be parsed: ") +
apersonalSerialBuffer);
apersonalSerialBuffer = "";
return false;
}
// Note: I cannot detect if no int is found because it will return 0 that is a valid cmd
acmdArg = apersonalSerialBuffer.substring(sepPos+1).toInt();
// All is fine
// I have to reset buffer before leaving
apersonalSerialBuffer = "";
return true;
}
void executeCommand(ECommand acmd, int &acmdArg) {
switch(acmd) {
case ecmdNoPwm:
// I erase acmdArg
acmdArg = 0;
analogWrite(ledPin, acmdArg);
Serial.println("cmd no pwm");
break;
case ecmdPwm:
analogWrite(ledPin, acmdArg);
Serial.print("cmd pwm:"); Serial.println(acmdArg);
break;
default:
analogWrite(ledPin, 0);
Serial.println("Bad cmd");
}
}

How to get module image name from an arbitrary address in Windows kernel space?

I'm trying to see how I can get a loaded module image name from an arbitrary address from the kernel code.
In user mode I would do this:
void* pAddr;
VOID* pBase;
WCHAR buff[MAX_PATH] = {0};
//Get address of some function in some module (just to test it)
pAddr = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetCurrentProcess");
//Get module base address
RtlPcToFileHeader(pAddr, &pBase);
//Get module image file name
GetModuleFileNameEx(GetCurrentProcess(), (HMODULE)pBase, buff, SIZEOF(buff));
Is there a way to do the same in kernel mode if I have pAddr that can point to some address in kernel or user space?
EDIT: While waiting for the answer I came up with my own code (using undocumented way of traversing PEB):
#ifdef CALLING_FROM_KERNEL_MODE
//Kernel mode
TEB* pTEB = (TEB*)PsGetCurrentThreadTeb();
#else
//User mode
#if defined(_M_X64)
//64-bit
TEB* pTEB = reinterpret_cast<TEB*>(__readgsqword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self)));
#else
//32-bit
TEB* pTEB = reinterpret_cast<TEB*>(__readfsdword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self)));
#endif
#endif
PEB* p_PEB = pTEB->ProcessEnvironmentBlock;
PEB_LDR_DATA* pPLD = p_PEB->Ldr;
const WCHAR* pModName = NULL;
LIST_ENTRY* pLE = &pPLD->InMemoryOrderModuleList;
LIST_ENTRY* pLE_Head = pLE;
while(pLE_Head != pLE->Flink)
{
PLDR_DATA_TABLE_ENTRY pLDTE = CONTAINING_RECORD(pLE, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
size_t szcbSizeOfImg = (size_t)pLDTE->Reserved3[1];
if((size_t)pAddr - (size_t)pLDTE->DllBase < szcbSizeOfImg)
{
pModName = pLDTE->FullDllName.Buffer;
break;
}
pLE = pLE->Flink;
}
The problem is that although it works from a user-mode, from a kernel mode PsGetCurrentThreadTeb() seems to return NULL. Does this mean kernel threads do not have a TEB?
this can be done by creating list of all loaded modules via ZwQuerySystemInformation with SystemModuleInformation
void fgt(PVOID *Callers, ULONG Count)
{
NTSTATUS status;
ULONG cb = 0x10000;
do
{
status = STATUS_INSUFFICIENT_RESOURCES;
if (PRTL_PROCESS_MODULES prpm = (PRTL_PROCESS_MODULES)ExAllocatePool(PagedPool, cb))
{
if (0 <= (status = NtQuerySystemInformation(SystemModuleInformation, prpm, cb, &cb)))
{
do
{
PVOID Caller = *Callers++;
if (ULONG NumberOfModules = prpm->NumberOfModules)
{
PRTL_PROCESS_MODULE_INFORMATION Modules = prpm->Modules;
do
{
if ((SIZE_T)Caller - (SIZE_T)Modules->ImageBase < Modules->ImageSize)
{
DbgPrint("%p> %s\n", Caller, Modules->FullPathName);
break;
}
} while (Modules++, --NumberOfModules);
}
} while (--Count);
}
ExFreePool(prpm);
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
}

Global variable being reset after each call

In my project I'm using a global variable but it's not working as expected because it is initialized everytime it's executed and honestly I don't know what could be going on.
The variable is cookingSignalReceived.
The program is structured as follows:
//File Controller.c:
while (1)
{
Controller_Run_State_Machine();
}
void Controller_Run_State_Machine(void)
{
/* start of activity code */
Inputs_ReadSensors();
Comms_CheckReceivedData();
Controller_UpdateSTM();
}
The problem is inside Comms file:
//File Comms.c
uint8_t cookingSignalReceived = 0;
void Comms_CheckReceivedData(void)
{
/* start of activity code */
uint8_t uartDataAvailable = Comms_R_UART0_checkIfDataAvailable();
if (uartDataAvailable == 1)
{
Comms_ParseReceivedCommand();
}
}
void Comms_ParseReceivedCommand(void)
{
/* start of activity code */
/* UserCode{499E2AA6-1F61-4753-9221-77F85E7B5D92}:YjMeKqu95e */
uint8_t CRC_check_OK = 0;
uint8_t* buffer;
/* UserCode{499E2AA6-1F61-4753-9221-77F85E7B5D92} */
Comms_R_UART0_resetFlag_dataAvailable();
buffer = Comms_R_UART0_getBuffer();
CRC_check_OK = Comms_crcCheck(buffer);
if (CRC_check_OK == 1)
{
Comms_processMessage(buffer); //<-- Variable is used in this function
}
}
Global variable is used inside Comms_processMessage(). The issue is that every time that the function is called, the global variable is set to the initial value. Do you find anything strange here?
EDITED:
void Comms_processMessage(uint8_t* buffer)
{
/* UserCode{BCB3B791-2DF9-492b-B53B-6FEB24BD8F77}:eyCoSfmCKb */
uint8_t message = buffer[0];
uint8_t param1 = buffer[1];
uint8_t param2 = buffer[2];
//---------------------------------------------------------------------
// START COOKING 1ST STEP REQUEST
//---------------------------------------------------------------------
if (message == MSG_COOK_1ST && param1 == START_PARAM)
{
// Wait for second frame
cookingSignalReceived = 1;
#ifdef DEBUG
R_UART0_Send("Cook 1st step!!", sizeof(char) * 15);
#endif
}
//---------------------------------------------------------------------
// START COOKING 2ND STEP REQUEST
//---------------------------------------------------------------------
else if (message == MSG_COOK_2ND && param1 == START_PARAM)
{
// Wait for second frame
if (cookingSignalReceived == 1)
{
Controller_signalsBufferEnqueue(cookingSignal);
}
#ifdef DEBUG
R_UART0_Send("Cook 2nd step!!", sizeof(char) * 15);
#endif
}
}
Note that my original idea was to use a local static variable but I was having the same issue so I tried with a global variable.
In certain cases the MCUs restart because unrecoverable errors or bad hardware settings. This should be the problem! A cause of this MCUs behaviour may be also bad pointers management.

Resources