I am trying to write a simple program using the Contiki-ng operating system for IoT platforms. First tests were ok, but something weird happens when trying to allocate dynamic memory. The test code I'm using is the following:
#include "contiki.h"
#include <stdio.h>
#include <stdlib.h>
PROCESS(main_process, "main_process");
AUTOSTART_PROCESSES(&main_process);
PROCESS_THREAD(main_process, ev, data) {
uint8_t *nonce;
int i;
PROCESS_BEGIN();
nonce = (uint8_t *) malloc(32 * sizeof(uint8_t));
if (nonce != NULL) {
for (i = 0; i < 32; i++)
nonce[i] = 0;
printf("Todo OK\n");
} else {
printf("Todo mal\n");
}
PROCESS_END();
}
When building the project, an error rises stating that "In funtion _sbrk_r: undefined reference to _sbrk". After looking some forums on internet, I managed to solve this problem by including the following line into the Makefile of the project:
MODULES += os/lib/newlib
This solves the problem because inside the path os/lib/newlib there is a file, syscalls.c, which implements the mentioned _sbrk function. However, the following error rises now:
I have not found anyone over the internet with the same problem, so I got stuck here. Additionally, I don't know why but since then, removing the line "MODULES += os/lib/newlib" from the Makefile does nothing, and the problem with _eheap and _heap persists without returning to the undefined _sbrk error. However, I believe that this weird error is due to something wrong with Eclipse IDE cleaning the project. The code from syscalls.c, if needed, is the following:
#include <sys/types.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
/*---------------------------------------------------------------------------*/
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
/**
* \brief Enlarges the allocated heap space
* \param incr Number of bytes by which to increase the heap space
* \return The previous end of heap on success (which is also a pointer to the
* start of the newly allocated memory if \p incr is positive), or
* <tt>(caddr_t)-1</tt> with \c errno set to \c ENOMEM on error
*/
caddr_t
_sbrk(int incr)
{
/*
* Newlib's _sbrk_r() assumes that this global errno variable is used here,
* which is different from the errno definition provided by <errno.h>.
*/
#undef errno
extern int errno;
/* Heap boundaries from linker script. */
extern uint8_t _heap;
extern uint8_t _eheap;
static uint8_t *heap_end = &_heap;
uint8_t *prev_heap_end = heap_end;
if(heap_end + incr > &_eheap) {
PRINTF("Out of heap space!\n");
errno = ENOMEM;
return (caddr_t)-1;
}
heap_end += incr;
return (caddr_t)prev_heap_end;
}
I hope someone could help me. I have read that Contiki gives more ways of using dynamic memory, but I need to do it this way because other parts of the code rely on the use of malloc and cannot be changed.
Thanks.
The short is that you almost certainly don't need and don't want to use malloc() on a Contiki-NG microcontroller. Use Contiki's memb module instead.
The long answer is that you can add the _heap symbol by using a linker script. Check example linker scripts provided by Contiki-NG on how to do that. For example, the script arch/cpu/cc26x0-cc13x0/cc26xx.ld (for the cc26x0-cc13x0 platform) places _heap immediately after the BSS segment:
.bss :
{
/* ... */
} > SRAM
_end = .; /* End of the .bss segment. */
/* ... */
_stack = .;
_heap = _stack;
Related
Situation
I'm following this to better understand the Linux kernel.
There's an example on writing a custom /proc interface. Here's a snippet from the sample code linked above - custom-proc.c:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/types.h>
#omitted
int create_new_proc_entry(void) {
int i;
char *DATA = "Hello People";
len = strlen(DATA);
msg = kmalloc((size_t) DATA_SIZE, GFP_KERNEL); // +1 for \0
if (msg != NULL) {
printk(KERN_INFO "Allocated memory for msg");
} else {
return -1;
}
strncpy(msg, DATA, len+1);
for (i=0; i < len +1 ; i++) {
printk(KERN_INFO "%c", msg[i]);
if (msg[i] == '\0') {
printk(KERN_INFO "YES");
}
}
proc = proc_create_data(MY_PROC_ENTRY, 0666, NULL, &proc_fops, msg);
if (proc) {
return 0;
}
return -1;
}
Since proc_create_data is not defined in the sample, I assume it must be defined somewhere in the kernel. I downloaded kernel 5x and search for all occurrence of proc_create_data in the kernel code and found that the only place where it was defined is in /include/linux/proc_fs.h:
#Omitted
#define proc_create_data(name, mode, parent, proc_ops, data) ({ NULL; })
#Omitted
extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
struct proc_dir_entry *,
const struct proc_ops *, void *)
That's it.
I read from here that in C, macros will be textually expanded and one can use it like a function.
If I applied it here, then after all the expansion, I will have
/include/linux/proc_fs.h:
#omitted
extern struct proc_dir_entry ({ NULL; })
custom-proc.c
#omitted
proc = ({ NULL; })
Which doesn't seem right to me.
I'm not new to programming but not familiar with C. I read The C programming Language by Brian W. Kernighan and Dennis M. Ritchie but there explanation of macro is the same with the link above.
Question (Main Course :))
How do I understand the proc_create_data function as defined in the kernel?
I'm not looking for a very detail technical answer, just a way to interpret that code so I can follow along examples and be able to read more kernel code when needed by myself.
Side Dish
I heard somewhere that the kernel, despite being written in C, has some differences to "normal" C. I'm not sure if that's true or the extent of the discrepancy, however.
If this is a trick employed by "kernel version of the C language" it would be helpful if anyone knows a link to explanation of such tricks.
I've already looked around on following resources but couldn't find such info:
www.kernel.org
https://kernelnewbies.org/
Linux Kernel Development - Robert Love
Linux System Programming - Robert Love
It looks like this in proc_fs.h:
#ifdef CONFIG_PROC_FS
extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
struct proc_dir_entry *,
const struct proc_ops *,
void *);
#else /* CONFIG_PROC_FS */
#define proc_create_data(name, mode, parent, proc_ops, data) ({NULL;})
#endif
If the user configured kernel without proc filesystem support, then the function call is expanded to a statement that just returns NULL. Note that ({...}) is a gcc extensions statement expression - do not use non-portable extensions in your code and prefer using static inline functions. The return value of a statement expression is the value of the last expression used - NULL in this case.
If CONFIG_PROC_FS is defined from user configuration, then proc/generic.c defines the function here just like any other function, and source files including proc_fs.h see the function declaration and do not see the macro.
I couldn't find the definition of proc_create_data function in Linux kernel
No worries - typing proc_create_data in elixir results in all 3 definitions mentioned in this answer. There are even multiple indexed kernel source code browsers on the net, with lxr as an example (but I see internal error right now on lxr). If not, you can index the source code on your computer with ctags or GNU GLOBAL and browse the code then.
How do I understand the proc_create_data function as defined in the kernel?
As any other function. No, the macro is not expanded with declaration - the compiler sees either the macro or the function declaration, depending if PROC_FS is enabled.
Side Dish I heard somewhere that the kernel, despite being written in C, has some differences to "normal" C.
Linux kernel specifically targets GNU GCC compiler, so it tends to use GNU C extensions, sometimes marked as GNU C.
I am debugging faulty serial connection on TrueSTM Atollic IDE.
Watch window, Expressions requires me to select a variable and display it as an array. Drawback is that I need to reselect that on each recompile, it gets very slow for +100 values and it doesn't look very clear to me.
So I have created function which simply prints out the bytes held in one of the buffers, those are then displayed to me over to SWV Console.
freertos.c
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
#include "stdbool.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
uint8_t X [4] = {0xFF,0xFF,0xFF,0xFF};
uint8_t * xt = X;
osThreadDef(CAN_Producer, FrameExtractorNEW, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(CAN_Producer), NULL);
void FrameExtractorNEW(void const * argument){
Print_Bytes(xt,4); // fails
printf("Cheese\n") // fails
}
main.c
#include "main.h"
#include "cmsis_os.h"
#include "can.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_CAN2_Init();
MX_CAN1_Init();
MX_USART3_UART_Init();
MX_FREERTOS_Init();
osKernelStart();
while (1)
{}
}
// accept pointer to first element, and number of consecutive byte values to display
void Print_Bytes(uint8_t * a1, int bytes_to_read){
for (int i = 0; i<bytes_to_read; i++){
printf("0x%02X " , *(a1+i));
}
}
Easy and straight forward stuff so far, or so it seems.
My problem is that if I try to use the function Print_Bytes() in the freertos.c it will work, but only provided that it has been invoked at least once prior in main.c. Printing out anything using printf() in main.c at least once will also make it work elsewhere in other files.
Without that 'enabling' program execution goes to HardFault_Handler() with following faults.
I have necessary includes for printf() and Print_Bytes() for the functions that call them but it doesn't seem to be enough to get it to work as I expect it should work.
I bet that the printf on the first run initializes some internal variables. In the main it uses the main program heap and the stack. If you use for the first time in the task it does it on the task heap and stack and none of the standard allocations may do not work in this context (printf uses the malloc function).
Personally I have written my own freeRTOS safe versions of this family of functions. It is very bad practice to use thread unsafe functions in the multi thread environment.
likely your minimal heap size is not big enough (ld file ide option ...)
default lib (nano etc ..) will call sbrake" to split stack en enlarge heap but it is nto mean to be used in rtos context so it wan't work if the stack pointer is not the main stack :(
So if you do a first print or malloc etc ...inside main before oskernel start it will help (sp is main stack) by enlarging your heap .
If you do it first time in a thread it wan't succeed cos "sp" use by sbrake is freertos task memory not the "main stack" thus printf fail to alloc mem
You may notice that printf rely or std lib malloc that is not re-entrant nor multi thread safe ... a safer formated print can be done via vsnprintf formating string to a task owned buffer.
I want to write a program using the new SCHED_DEADLINE scheduling policy available since Linux 3.14.
I start out with a simple program trying to use the sched_setattr function.
#include <sched.h>
int main(void)
{
// struct sched_attr attr;
// attr.size = sizeof(struct sched_attr);
// attr.sched_policy = SCHED_DEADLINE;
sched_setattr(0, (void*)0, 0);
return 0;
}
However when compiling I get the following error:
$gcc dead.c
dead.c: In function ‘main’:
dead.c:8:2: warning: implicit declaration of function ‘sched_setattr’ [-Wimplicit-function-declaration]
sched_setattr(0, (void*)0, 0);
^~~~~~~~~~~~~
/tmp/ccGxWxZE.o: In function `main':
dead.c:(.text+0x19): undefined reference to `sched_setattr'
collect2: error: ld returned 1 exit status
My system is running Ubuntu 16.10 Yakkety, with kernel 4.8.0-59-generic. The sched.h file included is found in /usr/include/sched.h and is provided by the package libc6-dev. This headerfile does not contain the function sched_setattr and friends that I am trying to use.
However the kernel (and kernel headers) I have installed comes with a sched.h header file containing the definitions I need. It is located at /usr/src/linux-headers-4.8.0-58/include/linux/sched.h, on my system.
So I naively think lets just build against the newer linux headers instead of the libc6-dev provided headers. My program will only run on this or newer kernels, but that is just fine.
I modify the first line to be: #include <linux/sched.h> and execute:
gcc -I/usr/src/linux-headers-$(uname -r)/include -I/usr/src/linux-headers-$(unam -r)/arch/x86/include dead.c
Now I am getting page after page of errors and warning. This does not seem the way to go.
What is the correct way to build a userspace program against a newer Linux headers than those that are provided by libc?
And subsequently how do I build the program above?
sched_setattr() is a syscall and doesn't seem to have one-to-one libc wrapper. You could do the wrapper yourself, something like this:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <linux/sched.h>
#include <sys/syscall.h>
#include <sys/types.h>
struct sched_attr {
uint32_t size; /* Size of this structure */
uint32_t sched_policy; /* Policy (SCHED_*) */
uint64_t sched_flags; /* Flags */
int32_t sched_nice; /* Nice value (SCHED_OTHER, SCHED_BATCH) */
uint32_t sched_priority; /* Static priority (SCHED_FIFO, SCHED_RR) */
/* Remaining fields are for SCHED_DEADLINE */
uint64_t sched_runtime;
uint64_t sched_deadline;
uint64_t sched_period;
};
static int sched_setattr (pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
return syscall (SYS_sched_setattr, pid, attr, flags);
}
int main (int argc, char *argv[])
{
struct sched_attr attr;
int res;
memset (&attr, 0, sizeof (struct sched_attr));
attr.size = sizeof (struct sched_attr);
res = sched_setattr (getpid (), &attr, 0);
if (res < 0) {
perror ("sched_setattr");
return 1;
}
return 0;
}
Looking at the errors reported when trying to include kernel header files required to get the definition of struct sched_attr and reading the comments found by Googling "kernel headers in user space", I really can't suggest trying to include kernel header files just for this.
So whenever I try to run my Makefile on my server, it always gives me the error is "Memory.c: 9 error: expected ')' before '*' token. But when I try to run it on my own computer, it works just fine. I've been trying to figure out what is wrong but can't seem to find it.
I've attached the 3 files that are used in this part of my program. Memory.c, Memory.h and ProcessInput.h.
This is Memory.c
/* Initializes memory */
#include <stdio.h>
#include <stdlib.h>
#include "memory.h"
void initializeMemory(memory** memArray, int memSize)
{
// Allocating space for memory array
*memArray = malloc(memSize * sizeof(memory));
if(*memArray == NULL)
{
fprintf(stderr, "Error allocating space for array of memory" );
exit(1); // exit(1) = Unsuccessful exit
}
// Initializing the contents within memory array
int i = 0;
for(i = 0; i < memSize; i ++)
{
((*memArray)[i]).occupied = false;
}
}
and this is Memory.h
// Definitions for Memory.c
#define bool int
#define true 1
#define false 0
#include "ProcessInput.h"
// Include guards to prevent redefinition of struct
#ifndef MEMORY_H
#define MEMORY_H
typedef struct memoryDetail
{
process process;
bool occupied;
} memory;
#endif
// Function declaration for memory.c
void initializeMemory(memory** memArray, int memSize);
the only thing used from ProcessInput.h is the process structure defined in ProcessInput.h
This is ProcessInput.h
// Include guards to prevent redefinition of struct
#ifndef PROCESSDETAIL_H
#define PROCESSDETAIL_H
typedef struct processDetail
{
int timeCreated;
int processID;
int memorySize;
int jobTime;
} process;
#endif
// function declarations for ProcessInput.c
void processInput(int* maxSize, int* count, process** processes, char* fileName);
I'm not too sure why it's giving me the error. I don't know where I'm supposed to be putting a missing right brace. Any advice is much appreciated!
edit: As informed, these are the following questions that I looked at but to not avail.
error: expected ‘)’ before ‘*’ token
Multiple of same error while compiling "error: expected ')' before '*' token
http://www.dreamincode.net/forums/topic/288956-error-expected-before-token/
thanks everyone for the help!
#include "memory.h" is different to #include "Memory.h" (i.e. C is case sensitive)
If you tried #include "myfile.h" instead of #include "MyFile.h" the error may be more obvious. In this case it just happens that the compiler finds the system memory.h.
<memory.h> is a header from C library of pre-standard era. It is quite possible that your standard library still provides it and the compiler takes that one instead of yours.
Try renaming your header file and see if it changes anything.
I am trying to write some C code which extracts the MAC no of a computer and prints it. Following is my code.
#ifndef WINVER
#define WINVER 0x0600
#endif
#include <stdlib.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <assert.h>
#pragma comment(lib, "IPHLPAPI.lib")
// BYTE has been typedefined as unsigned char
// DWORD has been typedefined as 32 bit unsigned long
static void PrintMACaddress(unsigned char MACData[])
{
printf("MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n",
MACData[0], MACData[1], MACData[2], MACData[3], MACData[4], MACData[5]);
}
// Fetches the MAC address and prints it
static void GetMACaddress(void){
IP_ADAPTER_ADDRESSES AdapterInfo[16]; // Allocate information for up to 16 NICs
DWORD dwBufLen = sizeof(AdapterInfo); // Save memory size of buffer
// Arguments for GetAdapterAddresses:
DWORD dwStatus = GetAdaptersAddresses(0, 0, NULL, AdapterInfo, &dwBufLen);
// [out] buffer to receive data
// [in] size of receive data buffer
assert(dwStatus == ERROR_SUCCESS); // Verify return value is valid, no buffer overflow
PIP_ADAPTER_ADDRESSES pAdapterInfo = AdapterInfo; // Contains pointer to current adapter info
do {
PrintMACaddress(pAdapterInfo->Address); // Print MAC address
pAdapterInfo = pAdapterInfo->Next; // Progress through linked list
}while(pAdapterInfo); // Terminate if last adapter
}
int main(){
GetMACaddress();
return 0;
}
But when I run my code it gives the following error :
Error : undefined reference to `GetAdaptersAddresses#20'
All though the GetAdaptersAddresses() function is included in iphlpapi.h library.
I also tried running the code using the GetAdaptersInfo() function but also gives the same kind of error.
I am using CodeBlocks to compile my code using the GNU GCC C++ 98 compiler version.
The operating system which I am working on is Windows 7.
Can anybody point out the reason for this kind of error.
GCC does not support #pragma comment and there is no equivalent. You will need to update your project settings to specifically link with the Iphlpapi.lib library.